diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-15 22:03:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-18 20:32:45 -0500 |
commit | df008c91f83583e662ac54aee00004afc3f1894d (patch) | |
tree | 800fd831c5beb1c4ec00b41d270462d52973a425 | |
parent | af31f412c7c7a3c0fda4bf4beaf0c85af1f263c8 (diff) |
net: Allow userns root to control llc, netfilter, netlink, packet, and xfrm
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 creation of af_key sockets.
Allow creation of llc sockets.
Allow creation of af_packet sockets.
Allow sending xfrm netlink control messages.
Allow binding to netlink multicast groups.
Allow sending to netlink multicast groups.
Allow adding and dropping netlink multicast groups.
Allow sending to all netlink multicast groups and port ids.
Allow reading the netfilter SO_IP_SET socket option.
Allow sending netfilter netlink messages.
Allow setting and getting ip_vs netfilter socket options.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/key/af_key.c | 2 | ||||
-rw-r--r-- | net/llc/af_llc.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_core.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 4 | ||||
-rw-r--r-- | net/netfilter/nfnetlink.c | 2 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 2 |
8 files changed, 9 insertions, 9 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 08897a3c7ec7..5b426a646544 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -141,7 +141,7 @@ static int pfkey_create(struct net *net, struct socket *sock, int protocol, | |||
141 | struct sock *sk; | 141 | struct sock *sk; |
142 | int err; | 142 | int err; |
143 | 143 | ||
144 | if (!capable(CAP_NET_ADMIN)) | 144 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
145 | return -EPERM; | 145 | return -EPERM; |
146 | if (sock->type != SOCK_RAW) | 146 | if (sock->type != SOCK_RAW) |
147 | return -ESOCKTNOSUPPORT; | 147 | return -ESOCKTNOSUPPORT; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index c2190005a114..88709882c464 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -160,7 +160,7 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol, | |||
160 | struct sock *sk; | 160 | struct sock *sk; |
161 | int rc = -ESOCKTNOSUPPORT; | 161 | int rc = -ESOCKTNOSUPPORT; |
162 | 162 | ||
163 | if (!capable(CAP_NET_RAW)) | 163 | if (!ns_capable(net->user_ns, CAP_NET_RAW)) |
164 | return -EPERM; | 164 | return -EPERM; |
165 | 165 | ||
166 | if (!net_eq(net, &init_net)) | 166 | if (!net_eq(net, &init_net)) |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 778465f217fa..fed899f600b2 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -1643,7 +1643,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) | |||
1643 | void *data; | 1643 | void *data; |
1644 | int copylen = *len, ret = 0; | 1644 | int copylen = *len, ret = 0; |
1645 | 1645 | ||
1646 | if (!capable(CAP_NET_ADMIN)) | 1646 | if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) |
1647 | return -EPERM; | 1647 | return -EPERM; |
1648 | if (optval != SO_IP_SET) | 1648 | if (optval != SO_IP_SET) |
1649 | return -EBADF; | 1649 | return -EBADF; |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index c6cebd560936..ec664cbb119f 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -2339,7 +2339,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
2339 | struct ip_vs_dest_user_kern udest; | 2339 | struct ip_vs_dest_user_kern udest; |
2340 | struct netns_ipvs *ipvs = net_ipvs(net); | 2340 | struct netns_ipvs *ipvs = net_ipvs(net); |
2341 | 2341 | ||
2342 | if (!capable(CAP_NET_ADMIN)) | 2342 | if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) |
2343 | return -EPERM; | 2343 | return -EPERM; |
2344 | 2344 | ||
2345 | if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_SET_MAX) | 2345 | if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_SET_MAX) |
@@ -2632,7 +2632,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
2632 | struct netns_ipvs *ipvs = net_ipvs(net); | 2632 | struct netns_ipvs *ipvs = net_ipvs(net); |
2633 | 2633 | ||
2634 | BUG_ON(!net); | 2634 | BUG_ON(!net); |
2635 | if (!capable(CAP_NET_ADMIN)) | 2635 | if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) |
2636 | return -EPERM; | 2636 | return -EPERM; |
2637 | 2637 | ||
2638 | if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX) | 2638 | if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX) |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index ffb92c03a358..58a09b7c3f6d 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -138,7 +138,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
138 | const struct nfnetlink_subsystem *ss; | 138 | const struct nfnetlink_subsystem *ss; |
139 | int type, err; | 139 | int type, err; |
140 | 140 | ||
141 | if (!capable(CAP_NET_ADMIN)) | 141 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
142 | return -EPERM; | 142 | return -EPERM; |
143 | 143 | ||
144 | /* All the messages must at least contain nfgenmsg */ | 144 | /* All the messages must at least contain nfgenmsg */ |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 4da797fa5ec5..c8a1eb6eca2d 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -612,7 +612,7 @@ retry: | |||
612 | static inline int netlink_capable(const struct socket *sock, unsigned int flag) | 612 | static inline int netlink_capable(const struct socket *sock, unsigned int flag) |
613 | { | 613 | { |
614 | return (nl_table[sock->sk->sk_protocol].flags & flag) || | 614 | return (nl_table[sock->sk->sk_protocol].flags & flag) || |
615 | capable(CAP_NET_ADMIN); | 615 | ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); |
616 | } | 616 | } |
617 | 617 | ||
618 | static void | 618 | static void |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index f262dbfc7f06..e639645e8fec 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2504,7 +2504,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | |||
2504 | __be16 proto = (__force __be16)protocol; /* weird, but documented */ | 2504 | __be16 proto = (__force __be16)protocol; /* weird, but documented */ |
2505 | int err; | 2505 | int err; |
2506 | 2506 | ||
2507 | if (!capable(CAP_NET_RAW)) | 2507 | if (!ns_capable(net->user_ns, CAP_NET_RAW)) |
2508 | return -EPERM; | 2508 | return -EPERM; |
2509 | if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW && | 2509 | if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW && |
2510 | sock->type != SOCK_PACKET) | 2510 | sock->type != SOCK_PACKET) |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 421f98444335..eb872b2e366e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -2349,7 +2349,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2349 | link = &xfrm_dispatch[type]; | 2349 | link = &xfrm_dispatch[type]; |
2350 | 2350 | ||
2351 | /* All operations require privileges, even GET */ | 2351 | /* All operations require privileges, even GET */ |
2352 | if (!capable(CAP_NET_ADMIN)) | 2352 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
2353 | return -EPERM; | 2353 | return -EPERM; |
2354 | 2354 | ||
2355 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 2355 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |