aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_sysfs_br.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_sysfs_br.c')
-rw-r--r--net/bridge/br_sysfs_br.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index c5c059333eab..5913a3a0047b 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -14,6 +14,7 @@
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/etherdevice.h>
17#include <linux/if_bridge.h> 18#include <linux/if_bridge.h>
18#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
@@ -36,7 +37,7 @@ static ssize_t store_bridge_parm(struct device *d,
36 unsigned long val; 37 unsigned long val;
37 int err; 38 int err;
38 39
39 if (!capable(CAP_NET_ADMIN)) 40 if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
40 return -EPERM; 41 return -EPERM;
41 42
42 val = simple_strtoul(buf, &endp, 0); 43 val = simple_strtoul(buf, &endp, 0);
@@ -132,7 +133,7 @@ static ssize_t store_stp_state(struct device *d,
132 char *endp; 133 char *endp;
133 unsigned long val; 134 unsigned long val;
134 135
135 if (!capable(CAP_NET_ADMIN)) 136 if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
136 return -EPERM; 137 return -EPERM;
137 138
138 val = simple_strtoul(buf, &endp, 0); 139 val = simple_strtoul(buf, &endp, 0);
@@ -165,7 +166,7 @@ static ssize_t store_group_fwd_mask(struct device *d,
165 char *endp; 166 char *endp;
166 unsigned long val; 167 unsigned long val;
167 168
168 if (!capable(CAP_NET_ADMIN)) 169 if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
169 return -EPERM; 170 return -EPERM;
170 171
171 val = simple_strtoul(buf, &endp, 0); 172 val = simple_strtoul(buf, &endp, 0);
@@ -297,23 +298,18 @@ static ssize_t store_group_addr(struct device *d,
297 const char *buf, size_t len) 298 const char *buf, size_t len)
298{ 299{
299 struct net_bridge *br = to_bridge(d); 300 struct net_bridge *br = to_bridge(d);
300 unsigned int new_addr[6]; 301 u8 new_addr[6];
301 int i; 302 int i;
302 303
303 if (!capable(CAP_NET_ADMIN)) 304 if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
304 return -EPERM; 305 return -EPERM;
305 306
306 if (sscanf(buf, "%x:%x:%x:%x:%x:%x", 307 if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
307 &new_addr[0], &new_addr[1], &new_addr[2], 308 &new_addr[0], &new_addr[1], &new_addr[2],
308 &new_addr[3], &new_addr[4], &new_addr[5]) != 6) 309 &new_addr[3], &new_addr[4], &new_addr[5]) != 6)
309 return -EINVAL; 310 return -EINVAL;
310 311
311 /* Must be 01:80:c2:00:00:0X */ 312 if (!is_link_local_ether_addr(new_addr))
312 for (i = 0; i < 5; i++)
313 if (new_addr[i] != br_group_address[i])
314 return -EINVAL;
315
316 if (new_addr[5] & ~0xf)
317 return -EINVAL; 313 return -EINVAL;
318 314
319 if (new_addr[5] == 1 || /* 802.3x Pause address */ 315 if (new_addr[5] == 1 || /* 802.3x Pause address */
@@ -337,7 +333,7 @@ static ssize_t store_flush(struct device *d,
337{ 333{
338 struct net_bridge *br = to_bridge(d); 334 struct net_bridge *br = to_bridge(d);
339 335
340 if (!capable(CAP_NET_ADMIN)) 336 if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
341 return -EPERM; 337 return -EPERM;
342 338
343 br_fdb_flush(br); 339 br_fdb_flush(br);