diff options
author | Gao feng <gaofeng@cn.fujitsu.com> | 2013-01-31 11:30:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-04 13:12:16 -0500 |
commit | bb12b8b26e197b21e3f28d5401bfee6f86a8d633 (patch) | |
tree | 638936cc9d889184e8b359049edb397638ee817c /net/bridge | |
parent | c5c351088ae76b46ae08dec1bb7f621e0721c78b (diff) |
netns: ebtable: allow unprivileged users to operate ebtables
ebt_table is a private resource of netns, operating ebtables
in one netns will not affect other netns, we can allow the
creator user of userns and netns to change the ebtables.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 5fe2ff3b01ef..8d493c91a562 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1472,16 +1472,17 @@ static int do_ebt_set_ctl(struct sock *sk, | |||
1472 | int cmd, void __user *user, unsigned int len) | 1472 | int cmd, void __user *user, unsigned int len) |
1473 | { | 1473 | { |
1474 | int ret; | 1474 | int ret; |
1475 | struct net *net = sock_net(sk); | ||
1475 | 1476 | ||
1476 | if (!capable(CAP_NET_ADMIN)) | 1477 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1477 | return -EPERM; | 1478 | return -EPERM; |
1478 | 1479 | ||
1479 | switch(cmd) { | 1480 | switch(cmd) { |
1480 | case EBT_SO_SET_ENTRIES: | 1481 | case EBT_SO_SET_ENTRIES: |
1481 | ret = do_replace(sock_net(sk), user, len); | 1482 | ret = do_replace(net, user, len); |
1482 | break; | 1483 | break; |
1483 | case EBT_SO_SET_COUNTERS: | 1484 | case EBT_SO_SET_COUNTERS: |
1484 | ret = update_counters(sock_net(sk), user, len); | 1485 | ret = update_counters(net, user, len); |
1485 | break; | 1486 | break; |
1486 | default: | 1487 | default: |
1487 | ret = -EINVAL; | 1488 | ret = -EINVAL; |
@@ -1494,14 +1495,15 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1494 | int ret; | 1495 | int ret; |
1495 | struct ebt_replace tmp; | 1496 | struct ebt_replace tmp; |
1496 | struct ebt_table *t; | 1497 | struct ebt_table *t; |
1498 | struct net *net = sock_net(sk); | ||
1497 | 1499 | ||
1498 | if (!capable(CAP_NET_ADMIN)) | 1500 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1499 | return -EPERM; | 1501 | return -EPERM; |
1500 | 1502 | ||
1501 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 1503 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
1502 | return -EFAULT; | 1504 | return -EFAULT; |
1503 | 1505 | ||
1504 | t = find_table_lock(sock_net(sk), tmp.name, &ret, &ebt_mutex); | 1506 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
1505 | if (!t) | 1507 | if (!t) |
1506 | return ret; | 1508 | return ret; |
1507 | 1509 | ||
@@ -2279,16 +2281,17 @@ static int compat_do_ebt_set_ctl(struct sock *sk, | |||
2279 | int cmd, void __user *user, unsigned int len) | 2281 | int cmd, void __user *user, unsigned int len) |
2280 | { | 2282 | { |
2281 | int ret; | 2283 | int ret; |
2284 | struct net *net = sock_net(sk); | ||
2282 | 2285 | ||
2283 | if (!capable(CAP_NET_ADMIN)) | 2286 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
2284 | return -EPERM; | 2287 | return -EPERM; |
2285 | 2288 | ||
2286 | switch (cmd) { | 2289 | switch (cmd) { |
2287 | case EBT_SO_SET_ENTRIES: | 2290 | case EBT_SO_SET_ENTRIES: |
2288 | ret = compat_do_replace(sock_net(sk), user, len); | 2291 | ret = compat_do_replace(net, user, len); |
2289 | break; | 2292 | break; |
2290 | case EBT_SO_SET_COUNTERS: | 2293 | case EBT_SO_SET_COUNTERS: |
2291 | ret = compat_update_counters(sock_net(sk), user, len); | 2294 | ret = compat_update_counters(net, user, len); |
2292 | break; | 2295 | break; |
2293 | default: | 2296 | default: |
2294 | ret = -EINVAL; | 2297 | ret = -EINVAL; |
@@ -2302,8 +2305,9 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, | |||
2302 | int ret; | 2305 | int ret; |
2303 | struct compat_ebt_replace tmp; | 2306 | struct compat_ebt_replace tmp; |
2304 | struct ebt_table *t; | 2307 | struct ebt_table *t; |
2308 | struct net *net = sock_net(sk); | ||
2305 | 2309 | ||
2306 | if (!capable(CAP_NET_ADMIN)) | 2310 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
2307 | return -EPERM; | 2311 | return -EPERM; |
2308 | 2312 | ||
2309 | /* try real handler in case userland supplied needed padding */ | 2313 | /* try real handler in case userland supplied needed padding */ |
@@ -2314,7 +2318,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, | |||
2314 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 2318 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
2315 | return -EFAULT; | 2319 | return -EFAULT; |
2316 | 2320 | ||
2317 | t = find_table_lock(sock_net(sk), tmp.name, &ret, &ebt_mutex); | 2321 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
2318 | if (!t) | 2322 | if (!t) |
2319 | return ret; | 2323 | return ret; |
2320 | 2324 | ||