diff mbox series

[v2,5/5] connector/cn_proc: Allow non-root users access

Message ID 20230315021850.2788946-6-anjali.k.kulkarni@oracle.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series Process connector bug fixes & enhancements | expand

Checks

Context Check Description
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Anjali Kulkarni March 15, 2023, 2:18 a.m. UTC
There were a couple of reasons for not allowing non-root users access
initially  - one is there was some point no proper receive buffer
management in place for netlink multicast. But that should be long
fixed. See link below for more context.

Second is that some of the messages may contain data that is root only. But
this should be handled with a finer granularity, which is being done at the
protocol layer.  The only problematic protocols are nf_queue and the
firewall netlink. Hence, this restriction for non-root access was relaxed
for NETLINK_ROUTE initially:
https://lore.kernel.org/all/20020612013101.A22399@wotan.suse.de/

This restriction has also been removed for following protocols:
NETLINK_KOBJECT_UEVENT, NETLINK_AUDIT, NETLINK_SOCK_DIAG,
NETLINK_GENERIC, NETLINK_SELINUX.

Since process connector messages are not sensitive (process fork, exit
notifications etc.), and anyone can read /proc data, we can allow non-root
access here. However, since process event notification is not the only
consumer of NETLINK_CONNECTOR, we can make this change even more
fine grained than the protocol level, by checking for multicast group
within the protocol.

Added a new function netlink_multicast_allowed(), which checks if the
protocol is NETLINK_CONNECTOR, and if multicast group is CN_IDX_PROC
(process event notification) - if so, then allow non-root acceess. For
other multicast groups of NETLINK_CONNECTOR, do not allow non-root
access.

Reason we need this change is we cannot run our DB application as root.

Signed-off-by: Anjali Kulkarni <anjali.k.kulkarni@oracle.com>
---
 drivers/connector/cn_proc.c |  7 -------
 net/netlink/af_netlink.c    | 13 ++++++++++++-
 2 files changed, 12 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 465c9c7a8f8b..d8e2f111da80 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -409,12 +409,6 @@  static void cn_proc_mcast_ctl(struct cn_msg *msg,
 	    !task_is_in_init_pid_ns(current))
 		return;
 
-	/* Can only change if privileged. */
-	if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
-		err = EPERM;
-		goto out;
-	}
-
 	if (msg->len == sizeof(*pinput)) {
 		pinput = (struct proc_input *)msg->data;
 		mc_op = pinput->mcast_op;
@@ -461,7 +455,6 @@  static void cn_proc_mcast_ctl(struct cn_msg *msg,
 		break;
 	}
 
-out:
 	cn_proc_ack(err, msg->seq, msg->ack);
 }
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index ad8ec18152cd..e4f5a1241a5d 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -938,6 +938,16 @@  bool netlink_net_capable(const struct sk_buff *skb, int cap)
 }
 EXPORT_SYMBOL(netlink_net_capable);
 
+static inline bool netlink_multicast_allowed(const struct socket *sock,
+					     unsigned long groups)
+{
+	if (sock->sk->sk_protocol == NETLINK_CONNECTOR) {
+		if (test_bit(CN_IDX_PROC - 1, &groups))
+			return true;
+	}
+	return false;
+}
+
 static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
 {
 	return (nl_table[sock->sk->sk_protocol].flags & flag) ||
@@ -1024,7 +1034,8 @@  static int netlink_bind(struct socket *sock, struct sockaddr *addr,
 	/* Only superuser is allowed to listen multicasts */
 	if (groups) {
 		if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
-			return -EPERM;
+			if (!netlink_multicast_allowed(sock, groups))
+				return -EPERM;
 		err = netlink_realloc_groups(sk);
 		if (err)
 			return err;