All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libnetfilter_conntrack: Add API support for passing bound file descriptor
@ 2017-04-04  0:01 Skylar Chang
  0 siblings, 0 replies; only message in thread
From: Skylar Chang @ 2017-04-04  0:01 UTC (permalink / raw)
  To: netfilter-devel, pablo, npendhar; +Cc: Skylar Chang

Add API support to accept pre-bound file descriptor from a
privileged process for creating a handle. Also clean-up
the handle without close the passing file descriptor. This
paves the path for privilege separation.

Change-Id: I815fb20cf1aadf931679d9470e6977a45681b4c9
---
 .../libnetfilter_conntrack.h                       |  6 ++
 src/main.c                                         | 69 +++++++++++++++++++---
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index b8d458c..1bc3529 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -40,10 +40,16 @@ struct nfct_handle;
  * [Open|close] a conntrack handler
  */
 extern struct nfct_handle *nfct_open(uint8_t, unsigned);
+extern struct nfct_handle *nfct_open2(uint8_t, unsigned, int);
 extern struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
 					  uint8_t subsys_id,
 					  unsigned int subscriptions);
+extern struct nfct_handle *nfct_open_nfnl2(struct nfnl_handle *nfnlh,
+					  uint8_t subsys_id,
+					  unsigned int subscriptions,
+					  bool bind);
 extern int nfct_close(struct nfct_handle *cth);
+extern int nfct_close2(struct nfct_handle *cth, bool keep_fd);
 
 extern int nfct_fd(struct nfct_handle *cth);
 extern const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth);
diff --git a/src/main.c b/src/main.c
index 2cbf79e..a136088 100644
--- a/src/main.c
+++ b/src/main.c
@@ -16,29 +16,38 @@ struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
 				   uint8_t subsys_id,
 				   unsigned int subscriptions)
 {
+
+	return nfct_open_nfnl2(nfnlh, subsys_id, subscriptions, true);
+}
+
+struct nfct_handle *nfct_open_nfnl2(struct nfnl_handle *nfnlh,
+				   uint8_t subsys_id,
+				   unsigned int subscriptions, bool bind)
+{
 	struct nfct_handle *cth;
 
 	cth = malloc(sizeof(struct nfct_handle));
 	if (!cth)
 		return NULL;
-	
 	memset(cth, 0, sizeof(*cth));
 	cth->nfnlh = nfnlh;
 
 	if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) {
-		cth->nfnlssh_ct = nfnl_subsys_open(cth->nfnlh, 
-						   NFNL_SUBSYS_CTNETLINK, 
+		cth->nfnlssh_ct = nfnl_subsys_open2(cth->nfnlh,
+						   NFNL_SUBSYS_CTNETLINK,
 						   IPCTNL_MSG_MAX,
-						   subscriptions);
+						   subscriptions,
+						   bind);
 		if (!cth->nfnlssh_ct)
 			goto out_free;
 	}
 
 	if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) {
-		cth->nfnlssh_exp = nfnl_subsys_open(cth->nfnlh,
+		cth->nfnlssh_exp = nfnl_subsys_open2(cth->nfnlh,
 						    NFNL_SUBSYS_CTNETLINK_EXP,
 						    IPCTNL_MSG_EXP_MAX,
-						    subscriptions);
+						    subscriptions,
+						    bind);
 		if (!cth->nfnlssh_exp)
 			goto out_free;
 	}
@@ -57,7 +66,6 @@ out_free:
 	free(cth);
 	return NULL;
 }
-
 /**
  * \defgroup LibrarySetup Library setup
  * @{
@@ -92,7 +100,39 @@ struct nfct_handle *nfct_open(uint8_t subsys_id, unsigned subscriptions)
 	nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions);
 	if (!nfcth)
 		nfnl_close(nfnlh);
+	return nfcth;
+}
 
+/**
+ * nfct_open2 - open a ctnetlink handler by given fd
+ * \param subsys_id can be NFNL_SUBSYS_CTNETLINK or NFNL_SUBSYS_CTNETLINK_EXP
+ * \param subscriptions ctnetlink groups to subscribe to events
+ * \param fd use bound file descriptor to get nfnl_handle
+ *
+ * This function returns a handler to send commands to and receive replies from
+ * kernel-space. You can pass the following subsystem IDs:
+ *
+ * - NFNL_SUBSYS_CTNETLINK: if you are only interested in conntrack operations
+ * (excluding expectations).
+ * - NFNL_SUBSYS_CTNETLINK_EXP: if you are only interested in expectation
+ * operations (exclude conntracks).
+ * - NFNL_SUBSYS_NONE: if you are interested in both conntrack and expectation
+ * operations.
+ *
+ * On error, NULL is returned and errno is explicitly set.
+ */
+struct nfct_handle *nfct_open2(uint8_t subsys_id, unsigned subscriptions, int fd)
+{
+	struct nfnl_handle *nfnlh = nfnl_open2(fd, false);
+	struct nfct_handle *nfcth;
+
+	if (!nfnlh)
+		return NULL;
+
+	nfcth = nfct_open_nfnl2(nfnlh, subsys_id, subscriptions, false);
+	if (!nfcth) {
+		nfnl_close2(nfnlh);
+	}
 	return nfcth;
 }
 
@@ -104,6 +144,18 @@ struct nfct_handle *nfct_open(uint8_t subsys_id, unsigned subscriptions)
  */
 int nfct_close(struct nfct_handle *cth)
 {
+	return nfct_close2(cth, false);
+}
+
+/**
+ * nfct_close2 - close a ctnetlink handler
+ * \param cth handler obtained via nfct_open()
+ * \param keep_fd to indicate not close the file descriptor
+ *
+ * This function returns -1 on error and errno is explicitly set.
+ */
+int nfct_close2(struct nfct_handle *cth, bool keep_fd)
+{
 	int err;
 
 	if (cth->nfnlssh_exp) {
@@ -131,6 +183,9 @@ int nfct_close(struct nfct_handle *cth)
 	cth->nfnl_cb_exp.data = NULL;
 	cth->nfnl_cb_exp.attr_count = 0;
 
+	if (keep_fd)
+		err = nfnl_close2(cth->nfnlh);
+	else
 	err = nfnl_close(cth->nfnlh);
 	free(cth);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-04-04  0:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-04  0:01 [PATCH] libnetfilter_conntrack: Add API support for passing bound file descriptor Skylar Chang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.