[Devel] [PATCH 1/2] net: allow containers create bridges with CAP_VE_NET_ADMIN
Pavel Tikhomirov
ptikhomirov at odin.com
Thu Jun 18 05:43:14 PDT 2015
Acked-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
On 06/18/2015 01:28 PM, Kirill Tkhai wrote:
> 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;
>
--
Best regards, Tikhomirov Pavel
Software Developer, Odin.
More information about the Devel
mailing list