[Devel] [PATCH 1/2] net: allow containers create bridges with CAP_VE_NET_ADMIN
Kirill Tkhai
ktkhai at odin.com
Thu Jun 18 03:28:39 PDT 2015
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>
---
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 d407219..2be924c 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -499,9 +499,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;
@@ -511,8 +515,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:
@@ -521,8 +523,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