[Devel] [PATCH RHEL7 COMMIT] ve/net: allow containers create bridges with CAP_VE_NET_ADMIN

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jun 18 06:41:56 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.14
------>
commit 450f5759c203dafd15d0645edee4a792cc6c2954
Author: Kirill Tkhai <ktkhai at odin.com>
Date:   Thu Jun 18 17:41:56 2015 +0400

    ve/net: allow containers create bridges with CAP_VE_NET_ADMIN
    
    Port patch diff-ve-net-ioctl-allow-change-net-device-name-with-CAP_VE_NET_ADMIN
    from 2.6.32:
    
    It is for docker task.
    
    CAP_NET_ADMIN is raised in vzctl(function CapBuildMask) for ve with
    VE_FEATURE_BRIDGE set(vzctl set $veid --features bridge:on --save).
    Because it is demanded by kernel to have CAP_NET_ADMIN for operations
    like add/delete bridge, set: forward delay, hello time, max age, ageing
    time, Spanning Tree Protocol state, via_phys_dev, priority or
    add/remove port.
    
    This patch makes that we no longer need to give this cap from vzctl for
    bridges feature. It allows to do all mentioned above operations with
    CAP_VE_NET_ADMIN.
    
    Test:
    In VE with VE_FEATURE_BRIDGE and without CAP_NET_ADMIN(tested  with
    12-th bit removed in caps bounding set on create of ve)
    bridge create/delete normaly:
    
    cat /proc/self/status | grep CapBnd
    CapBnd:	00000000fdecefff
    
    brctl addbr mybridge1
    brctl delbr mybridge1
    
    bridged docker-container works fine too(wordpress + mysql)
    
    v2: tested, found 3 more places where need to allow ve-admin, add
    description.
    v3: disable SIOCADDMULTI, SIOCDELMULTI, SIOCSIFHWBROADCAST,
    SIOCSMIIREG, SIOCBONDENSLAVE, SIOCBONDRELEASE, SIOCBONDSETHWADDR,
    SIOCBONDCHANGEACTIVE, SIOCSHWTSTAMP inside a CT.
    
    https://jira.sw.ru/browse/PSBM-29808
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at parallels.com>
    
    Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
    Acked-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 net/bridge/br_ioctl.c | 33 ++++++++++++++++++++++-----------
 net/core/dev_ioctl.c  |  8 ++++----
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 98447b8..45c4c22 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -89,7 +89,8 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd)
 	struct net_device *dev;
 	int ret;
 
-	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+	    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 		return -EPERM;
 
 	dev = __dev_get_by_index(net, ifindex);
@@ -179,25 +180,29 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	}
 
 	case BRCTL_SET_BRIDGE_FORWARD_DELAY:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		return br_set_forward_delay(br, args[1]);
 
 	case BRCTL_SET_BRIDGE_HELLO_TIME:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		return br_set_hello_time(br, args[1]);
 
 	case BRCTL_SET_BRIDGE_MAX_AGE:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		return br_set_max_age(br, args[1]);
 
 	case BRCTL_SET_AGEING_TIME:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		br->ageing_time = clock_t_to_jiffies(args[1]);
@@ -237,14 +242,16 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	}
 
 	case BRCTL_SET_BRIDGE_STP_STATE:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		br_stp_set_enabled(br, args[1]);
 		return 0;
 
 	case BRCTL_SET_BRIDGE_PRIORITY:
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		spin_lock_bh(&br->lock);
@@ -257,7 +264,8 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		struct net_bridge_port *p;
 		int ret;
 
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		spin_lock_bh(&br->lock);
@@ -274,7 +282,8 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		struct net_bridge_port *p;
 		int ret;
 
-		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(dev_net(dev)->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		spin_lock_bh(&br->lock);
@@ -331,7 +340,8 @@ static int old_deviceless(struct net *net, void __user *uarg)
 	{
 		char buf[IFNAMSIZ];
 
-		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ))
@@ -364,7 +374,8 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar
 	{
 		char buf[IFNAMSIZ];
 
-		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
+		    !ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
 
 		if (copy_from_user(buf, uarg, IFNAMSIZ))
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 77df687..021681b 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -502,9 +502,13 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	 *	- do not return a value
 	 */
 	case SIOCSIFMAP:
+	case SIOCSIFSLAVE:
 	case SIOCSIFMTU:
 	case SIOCSIFHWADDR:
 	case SIOCSIFFLAGS:
+	case SIOCSIFMETRIC:
+	case SIOCBRADDIF:
+	case SIOCBRDELIF:
 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
 				!ns_capable(net->user_ns, CAP_VE_NET_ADMIN))
 			return -EPERM;
@@ -514,8 +518,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 		rtnl_unlock();
 		return ret;
 
-	case SIOCSIFMETRIC:
-	case SIOCSIFSLAVE:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 	case SIOCSIFHWBROADCAST:
@@ -524,8 +526,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	case SIOCBONDRELEASE:
 	case SIOCBONDSETHWADDR:
 	case SIOCBONDCHANGEACTIVE:
-	case SIOCBRADDIF:
-	case SIOCBRDELIF:
 	case SIOCSHWTSTAMP:
 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 			return -EPERM;



More information about the Devel mailing list