[Devel] [PATCH] netlink: old behaviour for VE_NET_ADMIN capability check

Kirill Tkhai ktkhai at odin.com
Thu Jun 18 08:35:42 PDT 2015


Port path diff-ve-net-netlink-old-behaviour-for-VE_NET_ADMIN-capability-check
from 2.6.32:

During rebase to RHEL6u6 kernel behaviour of VE_NET_ADMIN capability check
for netlinks was changed. As result OpenVZ users have reported that zebra/quagga
on host does not work on new kernels:

ZEBRA: netlink-cmd error: Operation not permitted, type=RTM_NEWROUTE(24), seq=95, pid=0

This patch restores old behaviour in all affected cases:
CAP_NET_ADMIN should be checked before  CAP_VE_NET_ADMIN

https://jira.sw.ru/browse/PSBM-31125
https://bugzilla.openvz.org/show_bug.cgi?id=3137
https://bugzilla.openvz.org/show_bug.cgi?id=3157
https://bugzilla.openvz.org/show_bug.cgi?id=3160

Signed-off-by: Vasily Averin <vvs at parallels.com>
Acked-by: Kirill Tkhai <ktkhai at parallels.com>

This patch removes old RH6-specific behaviour and restores
standard behaviour. In the standard we need both of
these checks.

Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
---
 net/core/rtnetlink.c            |    3 ++-
 net/decnet/netfilter/dn_rtmsg.c |    3 ++-
 net/netfilter/nfnetlink.c       |   11 ++++++++---
 net/netlink/genetlink.c         |    3 ++-
 net/xfrm/xfrm_user.c            |    3 ++-
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d97abba..c50ea72 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2679,7 +2679,8 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	sz_idx = type>>2;
 	kind = type&3;
 
-	if (kind != 2 && !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
+	if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+			 !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 		return -EPERM;
 
 	if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 79e4ed4..5f7f200 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -107,7 +107,8 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
 	if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
 		return;
 
-	if (!capable(CAP_VE_NET_ADMIN))
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+	    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 		RCV_SKB_FAIL(-EPERM);
 
 	/* Eventually we might send routing messages too */
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index b8f00e6..a912eab 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -367,9 +367,14 @@ static void nfnetlink_rcv(struct sk_buff *skb)
 	    skb->len < nlh->nlmsg_len)
 		return;
 
-	if (!ns_capable(net->user_ns, CAP_VE_NET_ADMIN) ||
-	    (net->owner_ve != get_ve0() &&
-		NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_IPSET)) {
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+	    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN)) {
+		netlink_ack(skb, nlh, -EPERM);
+		return;
+	}
+
+	if (net->owner_ve != get_ve0() &&
+		NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_IPSET) {
 		netlink_ack(skb, nlh, -EPERM);
 		return;
 	}
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 86c23b4..65cf363 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -612,7 +612,8 @@ static int genl_family_rcv_msg(struct genl_family *family,
 		return -EOPNOTSUPP;
 
 	if ((ops->flags & GENL_ADMIN_PERM) &&
-	    !capable(CAP_VE_NET_ADMIN))
+	    !ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+	    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 		return -EPERM;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b77c92f..325cb0b 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2362,7 +2362,8 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	link = &xfrm_dispatch[type];
 
 	/* All operations require privileges, even GET */
-	if (!ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+	    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 		return -EPERM;
 
 	if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||




More information about the Devel mailing list