lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu,  2 Jul 2020 12:26:34 +1200
From:   Matt Bennett <matt.bennett@...iedtelesis.co.nz>
To:     netdev@...r.kernel.org
Cc:     zbr@...emap.net, ebiederm@...ssion.com,
        linux-kernel@...r.kernel.org,
        Matt Bennett <matt.bennett@...iedtelesis.co.nz>
Subject: [PATCH 4/5] connector: Prepare for supporting multiple namespaces

Extend the existing function definitions / call sites to start
passing the network namespace. For now we still only pass the
default namespace.

Signed-off-by: Matt Bennett <matt.bennett@...iedtelesis.co.nz>
---
 Documentation/driver-api/connector.rst |  6 +++---
 drivers/connector/cn_proc.c            |  5 +++--
 drivers/connector/cn_queue.c           |  5 +++--
 drivers/connector/connector.c          | 21 ++++++++++++---------
 drivers/hv/hv_utils_transport.c        |  6 ++++--
 drivers/md/dm-log-userspace-transfer.c |  6 ++++--
 drivers/video/fbdev/uvesafb.c          |  8 +++++---
 drivers/w1/w1_netlink.c                | 19 +++++++++++--------
 include/linux/connector.h              | 24 ++++++++++++++++--------
 samples/connector/cn_test.c            |  6 ++++--
 10 files changed, 65 insertions(+), 41 deletions(-)

diff --git a/Documentation/driver-api/connector.rst b/Documentation/driver-api/connector.rst
index c100c7482289..4fb1f73d76ad 100644
--- a/Documentation/driver-api/connector.rst
+++ b/Documentation/driver-api/connector.rst
@@ -25,9 +25,9 @@ handling, etc...  The Connector driver allows any kernelspace agents to use
 netlink based networking for inter-process communication in a significantly
 easier way::
 
-  int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
-  void cn_netlink_send_multi(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask);
-  void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask);
+  int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct net *, struct cn_msg *, struct netlink_skb_parms *));
+  void cn_netlink_send_multi(struct net *net, struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask);
+  void cn_netlink_send(struct net *net, struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask);
 
   struct cb_id
   {
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index d90aea555a21..9202be177a30 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -16,6 +16,7 @@
 #include <linux/ptrace.h>
 #include <linux/atomic.h>
 #include <linux/pid_namespace.h>
+#include <net/net_namespace.h>
 
 #include <linux/cn_proc.h>
 #include <linux/local_lock.h>
@@ -61,7 +62,7 @@ static inline void send_msg(struct cn_msg *msg)
 	 *
 	 * If cn_netlink_send() fails, the data is not sent.
 	 */
-	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_NOWAIT);
+	cn_netlink_send(&init_net, msg, 0, CN_IDX_PROC, GFP_NOWAIT);
 
 	local_unlock(&local_event.lock);
 }
@@ -343,7 +344,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
  * cn_proc_mcast_ctl
  * @data: message sent from userspace via the connector
  */
-static void cn_proc_mcast_ctl(struct cn_msg *msg,
+static void cn_proc_mcast_ctl(struct net *net, struct cn_msg *msg,
 			      struct netlink_skb_parms *nsp)
 {
 	enum proc_cn_mcast_op *mc_op = NULL;
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index a82ceeb37f26..22fdd2b149af 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -16,11 +16,12 @@
 #include <linux/suspend.h>
 #include <linux/connector.h>
 #include <linux/delay.h>
+#include <net/net_namespace.h>
 
 static struct cn_callback_entry *
 cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
 			      struct cb_id *id,
-			      void (*callback)(struct cn_msg *,
+			      void (*callback)(struct net *, struct cn_msg *,
 					       struct netlink_skb_parms *))
 {
 	struct cn_callback_entry *cbq;
@@ -58,7 +59,7 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
 
 int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
 			  struct cb_id *id,
-			  void (*callback)(struct cn_msg *,
+			  void (*callback)(struct net *, struct cn_msg *,
 					   struct netlink_skb_parms *))
 {
 	struct cn_callback_entry *cbq, *__cbq;
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 2d22d6bf52f2..82fcaa4d8be3 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -58,8 +58,8 @@ static int cn_already_initialized;
  * The message is sent to, the portid if given, the group if given, both if
  * both, or if both are zero then the group is looked up and sent there.
  */
-int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group,
-	gfp_t gfp_mask)
+int cn_netlink_send_mult(struct net *net, struct cn_msg *msg, u16 len,
+			 u32 portid, u32 __group, gfp_t gfp_mask)
 {
 	struct cn_callback_entry *__cbq;
 	unsigned int size;
@@ -118,17 +118,18 @@ int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group,
 EXPORT_SYMBOL_GPL(cn_netlink_send_mult);
 
 /* same as cn_netlink_send_mult except msg->len is used for len */
-int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group,
-	gfp_t gfp_mask)
+int cn_netlink_send(struct net *net, struct cn_msg *msg, u32 portid,
+		    u32 __group, gfp_t gfp_mask)
 {
-	return cn_netlink_send_mult(msg, msg->len, portid, __group, gfp_mask);
+	return cn_netlink_send_mult(net, msg, msg->len, portid, __group,
+				    gfp_mask);
 }
 EXPORT_SYMBOL_GPL(cn_netlink_send);
 
 /*
  * Callback helper - queues work and setup destructor for given data.
  */
-static int cn_call_callback(struct sk_buff *skb)
+static int cn_call_callback(struct net *net, struct sk_buff *skb)
 {
 	struct nlmsghdr *nlh;
 	struct cn_callback_entry *i, *cbq = NULL;
@@ -153,7 +154,7 @@ static int cn_call_callback(struct sk_buff *skb)
 	spin_unlock_bh(&dev->cbdev->queue_lock);
 
 	if (cbq != NULL) {
-		cbq->callback(msg, nsp);
+		cbq->callback(net, msg, nsp);
 		kfree_skb(skb);
 		cn_queue_release_callback(cbq);
 		err = 0;
@@ -172,6 +173,8 @@ static void cn_rx_skb(struct sk_buff *skb)
 	struct nlmsghdr *nlh;
 	int len, err;
 
+	struct net *net = sock_net(skb->sk);
+
 	if (skb->len >= NLMSG_HDRLEN) {
 		nlh = nlmsg_hdr(skb);
 		len = nlmsg_len(nlh);
@@ -181,7 +184,7 @@ static void cn_rx_skb(struct sk_buff *skb)
 		    len > CONNECTOR_MAX_MSG_SIZE)
 			return;
 
-		err = cn_call_callback(skb_get(skb));
+		err = cn_call_callback(net, skb_get(skb));
 		if (err < 0)
 			kfree_skb(skb);
 	}
@@ -194,7 +197,7 @@ static void cn_rx_skb(struct sk_buff *skb)
  * May sleep.
  */
 int cn_add_callback(struct cb_id *id, const char *name,
-		    void (*callback)(struct cn_msg *,
+		    void (*callback)(struct net *, struct cn_msg *,
 				     struct netlink_skb_parms *))
 {
 	int err;
diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c
index eb2833d2b5d0..1a67efe59e91 100644
--- a/drivers/hv/hv_utils_transport.c
+++ b/drivers/hv/hv_utils_transport.c
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
+#include <net/net_namespace.h>
 
 #include "hyperv_vmbus.h"
 #include "hv_utils_transport.h"
@@ -181,7 +182,8 @@ static int hvt_op_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+static void hvt_cn_callback(struct net *net, struct cn_msg *msg,
+			    struct netlink_skb_parms *nsp)
 {
 	struct hvutil_transport *hvt, *hvt_found = NULL;
 
@@ -231,7 +233,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len,
 		cn_msg->id.val = hvt->cn_id.val;
 		cn_msg->len = len;
 		memcpy(cn_msg->data, msg, len);
-		ret = cn_netlink_send(cn_msg, 0, 0, GFP_ATOMIC);
+		ret = cn_netlink_send(&init_net, cn_msg, 0, 0, GFP_ATOMIC);
 		kfree(cn_msg);
 		/*
 		 * We don't know when netlink messages are delivered but unlike
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index fdf8ec304f8d..0e835acf14da 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -12,6 +12,7 @@
 #include <linux/connector.h>
 #include <linux/device-mapper.h>
 #include <linux/dm-log-userspace.h>
+#include <net/net_namespace.h>
 
 #include "dm-log-userspace-transfer.h"
 
@@ -66,7 +67,7 @@ static int dm_ulog_sendto_server(struct dm_ulog_request *tfr)
 	msg->seq = tfr->seq;
 	msg->len = sizeof(struct dm_ulog_request) + tfr->data_size;
 
-	r = cn_netlink_send(msg, 0, 0, gfp_any());
+	r = cn_netlink_send(&init_net, msg, 0, 0, gfp_any());
 
 	return r;
 }
@@ -130,7 +131,8 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
  * This is the connector callback that delivers data
  * that was sent from userspace.
  */
-static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+static void cn_ulog_callback(struct net *net, struct cn_msg *msg,
+			     struct netlink_skb_parms *nsp)
 {
 	struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
 
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index def14ac0ebe1..f9b6ed7b97f2 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <video/edid.h>
 #include <video/uvesafb.h>
+#include <net/net_namespace.h>
 #ifdef CONFIG_X86
 #include <video/vga.h>
 #endif
@@ -69,7 +70,8 @@ static DEFINE_MUTEX(uvfb_lock);
  * find the kernel part of the task struct, copy the registers and
  * the buffer contents and then complete the task.
  */
-static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+static void uvesafb_cn_callback(struct net *net, struct cn_msg *msg,
+				struct netlink_skb_parms *nsp)
 {
 	struct uvesafb_task *utask;
 	struct uvesafb_ktask *task;
@@ -194,7 +196,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
 	uvfb_tasks[seq] = task;
 	mutex_unlock(&uvfb_lock);
 
-	err = cn_netlink_send(m, 0, 0, GFP_KERNEL);
+	err = cn_netlink_send(&init_net, m, 0, 0, GFP_KERNEL);
 	if (err == -ESRCH) {
 		/*
 		 * Try to start the userspace helper if sending
@@ -206,7 +208,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
 			pr_err("make sure that the v86d helper is installed and executable\n");
 		} else {
 			v86d_started = 1;
-			err = cn_netlink_send(m, 0, 0, gfp_any());
+			err = cn_netlink_send(&init_net, m, 0, 0, gfp_any());
 			if (err == -ENOBUFS)
 				err = 0;
 		}
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index fa490aa4407c..246844b61613 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -7,6 +7,7 @@
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/connector.h>
+#include <net/net_namespace.h>
 
 #include "w1_internal.h"
 #include "w1_netlink.h"
@@ -64,8 +65,8 @@ static void w1_unref_block(struct w1_cb_block *block)
 	if (atomic_sub_return(1, &block->refcnt) == 0) {
 		u16 len = w1_reply_len(block);
 		if (len) {
-			cn_netlink_send_mult(block->first_cn, len,
-				block->portid, 0, GFP_KERNEL);
+			cn_netlink_send_mult(&init_net, block->first_cn, len,
+					     block->portid, 0, GFP_KERNEL);
 		}
 		kfree(block);
 	}
@@ -83,7 +84,8 @@ static void w1_reply_make_space(struct w1_cb_block *block, u16 space)
 {
 	u16 len = w1_reply_len(block);
 	if (len + space >= block->maxlen) {
-		cn_netlink_send_mult(block->first_cn, len, block->portid, 0, GFP_KERNEL);
+		cn_netlink_send_mult(&init_net, block->first_cn, len,
+				     block->portid, 0, GFP_KERNEL);
 		block->first_cn->len = 0;
 		block->cn = NULL;
 		block->msg = NULL;
@@ -201,7 +203,7 @@ static void w1_netlink_send_error(struct cn_msg *cn, struct w1_netlink_msg *msg,
 	packet.cn.len = sizeof(packet.msg);
 	packet.msg.len = 0;
 	packet.msg.status = (u8)-error;
-	cn_netlink_send(&packet.cn, portid, 0, GFP_KERNEL);
+	cn_netlink_send(&init_net, &packet.cn, portid, 0, GFP_KERNEL);
 }
 
 /**
@@ -228,7 +230,7 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
 	memcpy(&packet.msg, msg, sizeof(*msg));
 	packet.msg.len = 0;
 
-	cn_netlink_send(&packet.cn, 0, 0, GFP_KERNEL);
+	cn_netlink_send(&init_net, &packet.cn, 0, 0, GFP_KERNEL);
 }
 
 static void w1_send_slave(struct w1_master *dev, u64 rn)
@@ -421,7 +423,7 @@ static int w1_process_command_root(struct cn_msg *req_cn, u32 portid)
 	mutex_lock(&w1_mlock);
 	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
 		if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
-			cn_netlink_send(cn, portid, 0, GFP_KERNEL);
+			cn_netlink_send(&init_net, cn, portid, 0, GFP_KERNEL);
 			cn->len = sizeof(struct w1_netlink_msg);
 			msg->len = 0;
 			id = (u32 *)msg->data;
@@ -432,7 +434,7 @@ static int w1_process_command_root(struct cn_msg *req_cn, u32 portid)
 		cn->len += sizeof(*id);
 		id++;
 	}
-	cn_netlink_send(cn, portid, 0, GFP_KERNEL);
+	cn_netlink_send(&init_net, cn, portid, 0, GFP_KERNEL);
 	mutex_unlock(&w1_mlock);
 
 	kfree(cn);
@@ -532,7 +534,8 @@ static void w1_list_count_cmds(struct w1_netlink_msg *msg, int *cmd_count,
 	}
 }
 
-static void w1_cn_callback(struct cn_msg *cn, struct netlink_skb_parms *nsp)
+static void w1_cn_callback(struct net *net, struct cn_msg *cn,
+			   struct netlink_skb_parms *nsp)
 {
 	struct w1_netlink_msg *msg = (struct w1_netlink_msg *)(cn + 1);
 	struct w1_slave *sl;
diff --git a/include/linux/connector.h b/include/linux/connector.h
index cb732643471b..8e9385eb18f8 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -40,7 +40,8 @@ struct cn_callback_entry {
 	struct cn_queue_dev *pdev;
 
 	struct cn_callback_id id;
-	void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
+	void (*callback)(struct net *, struct cn_msg *,
+			 struct netlink_skb_parms *);
 
 	u32 seq, group;
 };
@@ -62,10 +63,12 @@ struct cn_dev {
  *		in-kernel users.
  * @name:	connector's callback symbolic name.
  * @callback:	connector's callback.
- * 		parameters are %cn_msg and the sender's credentials
+ *		parameters are network namespace, %cn_msg and
+ *		the sender's credentials
  */
 int cn_add_callback(struct cb_id *id, const char *name,
-		    void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
+		    void (*callback)(struct net *, struct cn_msg *,
+				     struct netlink_skb_parms *));
 /**
  * cn_del_callback() - Unregisters new callback with connector core.
  *
@@ -75,8 +78,9 @@ void cn_del_callback(struct cb_id *id);
 
 
 /**
- * cn_netlink_send_mult - Sends message to the specified groups.
+ * cn_netlink_send_mult - Sends messages to the specified groups.
  *
+ * @net:	network namespace
  * @msg: 	message header(with attached data).
  * @len:	Number of @msg to be sent.
  * @portid:	destination port.
@@ -96,11 +100,13 @@ void cn_del_callback(struct cb_id *id);
  *
  * If there are no listeners for given group %-ESRCH can be returned.
  */
-int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask);
+int cn_netlink_send_mult(struct net *net, struct cn_msg *msg, u16 len,
+			 u32 portid, u32 group, gfp_t gfp_mask);
 
 /**
- * cn_netlink_send_mult - Sends message to the specified groups.
+ * cn_netlink_send - Sends message to the specified groups.
  *
+ * @net:	network namespace
  * @msg:	message header(with attached data).
  * @portid:	destination port.
  *		If non-zero the message will be sent to the given port,
@@ -119,11 +125,13 @@ int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp
  *
  * If there are no listeners for given group %-ESRCH can be returned.
  */
-int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask);
+int cn_netlink_send(struct net *net, struct cn_msg *msg, u32 portid, u32 group,
+		    gfp_t gfp_mask);
 
 int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
 			  struct cb_id *id,
-			  void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
+			  void (*callback)(struct net *, struct cn_msg *,
+					   struct netlink_skb_parms *));
 void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
 void cn_queue_release_callback(struct cn_callback_entry *);
 
diff --git a/samples/connector/cn_test.c b/samples/connector/cn_test.c
index 0958a171d048..9eaf40bbd714 100644
--- a/samples/connector/cn_test.c
+++ b/samples/connector/cn_test.c
@@ -16,13 +16,15 @@
 #include <linux/timer.h>
 
 #include <linux/connector.h>
+#include <net/net_namespace.h>
 
 static struct cb_id cn_test_id = { CN_NETLINK_USERS + 3, 0x456 };
 static char cn_test_name[] = "cn_test";
 static struct sock *nls;
 static struct timer_list cn_test_timer;
 
-static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+static void cn_test_callback(struct net *net, struct cn_msg *msg,
+			     struct netlink_skb_parms *nsp)
 {
 	pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
 	        __func__, jiffies, msg->id.idx, msg->id.val,
@@ -132,7 +134,7 @@ static void cn_test_timer_func(struct timer_list *unused)
 
 		memcpy(m + 1, data, m->len);
 
-		cn_netlink_send(m, 0, 0, GFP_ATOMIC);
+		cn_netlink_send(&init_net, m, 0, 0, GFP_ATOMIC);
 		kfree(m);
 	}
 
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ