aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-11-15 22:03:07 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-18 20:32:45 -0500
commitdf008c91f83583e662ac54aee00004afc3f1894d (patch)
tree800fd831c5beb1c4ec00b41d270462d52973a425
parentaf31f412c7c7a3c0fda4bf4beaf0c85af1f263c8 (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.c2
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/netfilter/ipset/ip_set_core.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c4
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/xfrm/xfrm_user.c2
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:
612static inline int netlink_capable(const struct socket *sock, unsigned int flag) 612static 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
618static void 618static 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) ||