diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-15 22:03:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-18 20:33:00 -0500 |
commit | cb99050305f0ffed0d0ee0d95f1d6645af4d3237 (patch) | |
tree | e9e215981cf3ad1487c5d5ede58bc34c0f97ddb1 /net/bridge/br_ioctl.c | |
parent | df008c91f83583e662ac54aee00004afc3f1894d (diff) |
net: Allow userns root to control the network bridge code.
Allow an unpriviled user who has created a user namespace, and then
created a network namespace to effectively use the new network
namespace, by reducing capable(CAP_NET_ADMIN) and
capable(CAP_NET_RAW) calls to be ns_capable(net->user_ns,
CAP_NET_ADMIN), or capable(net->user_ns, CAP_NET_RAW) calls.
Allow setting bridge paramters via sysfs.
Allow all of the bridge ioctls:
BRCTL_ADD_IF
BRCTL_DEL_IF
BRCTL_SET_BRDIGE_FORWARD_DELAY
BRCTL_SET_BRIDGE_HELLO_TIME
BRCTL_SET_BRIDGE_MAX_AGE
BRCTL_SET_BRIDGE_AGING_TIME
BRCTL_SET_BRIDGE_STP_STATE
BRCTL_SET_BRIDGE_PRIORITY
BRCTL_SET_PORT_PRIORITY
BRCTL_SET_PATH_COST
BRCTL_ADD_BRIDGE
BRCTL_DEL_BRDIGE
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_ioctl.c')
-rw-r--r-- | net/bridge/br_ioctl.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 7222fe1d5460..cd8c3a44ab7d 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c | |||
@@ -85,13 +85,14 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf, | |||
85 | /* called with RTNL */ | 85 | /* called with RTNL */ |
86 | static int add_del_if(struct net_bridge *br, int ifindex, int isadd) | 86 | static int add_del_if(struct net_bridge *br, int ifindex, int isadd) |
87 | { | 87 | { |
88 | struct net *net = dev_net(br->dev); | ||
88 | struct net_device *dev; | 89 | struct net_device *dev; |
89 | int ret; | 90 | int ret; |
90 | 91 | ||
91 | if (!capable(CAP_NET_ADMIN)) | 92 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
92 | return -EPERM; | 93 | return -EPERM; |
93 | 94 | ||
94 | dev = __dev_get_by_index(dev_net(br->dev), ifindex); | 95 | dev = __dev_get_by_index(net, ifindex); |
95 | if (dev == NULL) | 96 | if (dev == NULL) |
96 | return -EINVAL; | 97 | return -EINVAL; |
97 | 98 | ||
@@ -178,25 +179,25 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
178 | } | 179 | } |
179 | 180 | ||
180 | case BRCTL_SET_BRIDGE_FORWARD_DELAY: | 181 | case BRCTL_SET_BRIDGE_FORWARD_DELAY: |
181 | if (!capable(CAP_NET_ADMIN)) | 182 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
182 | return -EPERM; | 183 | return -EPERM; |
183 | 184 | ||
184 | return br_set_forward_delay(br, args[1]); | 185 | return br_set_forward_delay(br, args[1]); |
185 | 186 | ||
186 | case BRCTL_SET_BRIDGE_HELLO_TIME: | 187 | case BRCTL_SET_BRIDGE_HELLO_TIME: |
187 | if (!capable(CAP_NET_ADMIN)) | 188 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
188 | return -EPERM; | 189 | return -EPERM; |
189 | 190 | ||
190 | return br_set_hello_time(br, args[1]); | 191 | return br_set_hello_time(br, args[1]); |
191 | 192 | ||
192 | case BRCTL_SET_BRIDGE_MAX_AGE: | 193 | case BRCTL_SET_BRIDGE_MAX_AGE: |
193 | if (!capable(CAP_NET_ADMIN)) | 194 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
194 | return -EPERM; | 195 | return -EPERM; |
195 | 196 | ||
196 | return br_set_max_age(br, args[1]); | 197 | return br_set_max_age(br, args[1]); |
197 | 198 | ||
198 | case BRCTL_SET_AGEING_TIME: | 199 | case BRCTL_SET_AGEING_TIME: |
199 | if (!capable(CAP_NET_ADMIN)) | 200 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
200 | return -EPERM; | 201 | return -EPERM; |
201 | 202 | ||
202 | br->ageing_time = clock_t_to_jiffies(args[1]); | 203 | br->ageing_time = clock_t_to_jiffies(args[1]); |
@@ -236,14 +237,14 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
236 | } | 237 | } |
237 | 238 | ||
238 | case BRCTL_SET_BRIDGE_STP_STATE: | 239 | case BRCTL_SET_BRIDGE_STP_STATE: |
239 | if (!capable(CAP_NET_ADMIN)) | 240 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
240 | return -EPERM; | 241 | return -EPERM; |
241 | 242 | ||
242 | br_stp_set_enabled(br, args[1]); | 243 | br_stp_set_enabled(br, args[1]); |
243 | return 0; | 244 | return 0; |
244 | 245 | ||
245 | case BRCTL_SET_BRIDGE_PRIORITY: | 246 | case BRCTL_SET_BRIDGE_PRIORITY: |
246 | if (!capable(CAP_NET_ADMIN)) | 247 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
247 | return -EPERM; | 248 | return -EPERM; |
248 | 249 | ||
249 | spin_lock_bh(&br->lock); | 250 | spin_lock_bh(&br->lock); |
@@ -256,7 +257,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
256 | struct net_bridge_port *p; | 257 | struct net_bridge_port *p; |
257 | int ret; | 258 | int ret; |
258 | 259 | ||
259 | if (!capable(CAP_NET_ADMIN)) | 260 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
260 | return -EPERM; | 261 | return -EPERM; |
261 | 262 | ||
262 | spin_lock_bh(&br->lock); | 263 | spin_lock_bh(&br->lock); |
@@ -273,7 +274,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
273 | struct net_bridge_port *p; | 274 | struct net_bridge_port *p; |
274 | int ret; | 275 | int ret; |
275 | 276 | ||
276 | if (!capable(CAP_NET_ADMIN)) | 277 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
277 | return -EPERM; | 278 | return -EPERM; |
278 | 279 | ||
279 | spin_lock_bh(&br->lock); | 280 | spin_lock_bh(&br->lock); |
@@ -330,7 +331,7 @@ static int old_deviceless(struct net *net, void __user *uarg) | |||
330 | { | 331 | { |
331 | char buf[IFNAMSIZ]; | 332 | char buf[IFNAMSIZ]; |
332 | 333 | ||
333 | if (!capable(CAP_NET_ADMIN)) | 334 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
334 | return -EPERM; | 335 | return -EPERM; |
335 | 336 | ||
336 | if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ)) | 337 | if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ)) |
@@ -360,7 +361,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar | |||
360 | { | 361 | { |
361 | char buf[IFNAMSIZ]; | 362 | char buf[IFNAMSIZ]; |
362 | 363 | ||
363 | if (!capable(CAP_NET_ADMIN)) | 364 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
364 | return -EPERM; | 365 | return -EPERM; |
365 | 366 | ||
366 | if (copy_from_user(buf, uarg, IFNAMSIZ)) | 367 | if (copy_from_user(buf, uarg, IFNAMSIZ)) |