[Devel] [PATCH RHEL7 COMMIT] ve/netlink: old behaviour for VE_NET_ADMIN capability check

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jun 22 02:09:39 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.15
------>
commit 53477512384ab46be05da4f2a6b76b96a94963ac
Author: Kirill Tkhai <ktkhai at odin.com>
Date:   Mon Jun 22 13:09:34 2015 +0400

    ve/netlink: old behaviour for VE_NET_ADMIN capability check
    
    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 b8f00e60..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