Commit 52e804c6dfaa5df1e4b0e290357b82ad4e4cda2c

Authored by Eric W. Biederman
Committed by David S. Miller
1 parent 5e1fccc0bf

net: Allow userns root to control ipv4

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.

Settings that merely control a single network device are allowed.
Either the network device is a logical network device where
restrictions make no difference or the network device is hardware NIC
that has been explicity moved from the initial network namespace.

In general policy and network stack state changes are allowed
while resource control is left unchanged.

Allow creating raw sockets.
Allow the SIOCSARP ioctl to control the arp cache.
Allow the SIOCSIFFLAG ioctl to allow setting network device flags.
Allow the SIOCSIFADDR ioctl to allow setting a netdevice ipv4 address.
Allow the SIOCSIFBRDADDR ioctl to allow setting a netdevice ipv4 broadcast address.
Allow the SIOCSIFDSTADDR ioctl to allow setting a netdevice ipv4 destination address.
Allow the SIOCSIFNETMASK ioctl to allow setting a netdevice ipv4 netmask.
Allow the SIOCADDRT and SIOCDELRT ioctls to allow adding and deleting ipv4 routes.

Allow the SIOCADDTUNNEL, SIOCCHGTUNNEL and SIOCDELTUNNEL ioctls for
adding, changing and deleting gre tunnels.

Allow the SIOCADDTUNNEL, SIOCCHGTUNNEL and SIOCDELTUNNEL ioctls for
adding, changing and deleting ipip tunnels.

Allow the SIOCADDTUNNEL, SIOCCHGTUNNEL and SIOCDELTUNNEL ioctls for
adding, changing and deleting ipsec virtual tunnel interfaces.

Allow setting the MRT_INIT, MRT_DONE, MRT_ADD_VIF, MRT_DEL_VIF, MRT_ADD_MFC,
MRT_DEL_MFC, MRT_ASSERT, MRT_PIM, MRT_TABLE socket options on multicast routing
sockets.

Allow setting and receiving IPOPT_CIPSO, IP_OPT_SEC, IP_OPT_SID and
arbitrary ip options.

Allow setting IP_SEC_POLICY/IP_XFRM_POLICY ipv4 socket option.
Allow setting the IP_TRANSPARENT ipv4 socket option.
Allow setting the TCP_REPAIR socket option.
Allow setting the TCP_CONGESTION socket option.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 14 changed files with 30 additions and 27 deletions Side-by-side Diff

... ... @@ -346,7 +346,8 @@
346 346 }
347 347  
348 348 err = -EPERM;
349   - if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
  349 + if (sock->type == SOCK_RAW && !kern &&
  350 + !ns_capable(net->user_ns, CAP_NET_RAW))
350 351 goto out_rcu_unlock;
351 352  
352 353 err = -EAFNOSUPPORT;
... ... @@ -1161,7 +1161,7 @@
1161 1161 switch (cmd) {
1162 1162 case SIOCDARP:
1163 1163 case SIOCSARP:
1164   - if (!capable(CAP_NET_ADMIN))
  1164 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1165 1165 return -EPERM;
1166 1166 case SIOCGARP:
1167 1167 err = copy_from_user(&r, arg, sizeof(struct arpreq));
... ... @@ -730,7 +730,7 @@
730 730  
731 731 case SIOCSIFFLAGS:
732 732 ret = -EPERM;
733   - if (!capable(CAP_NET_ADMIN))
  733 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
734 734 goto out;
735 735 break;
736 736 case SIOCSIFADDR: /* Set interface address (and family) */
... ... @@ -738,7 +738,7 @@
738 738 case SIOCSIFDSTADDR: /* Set the destination address */
739 739 case SIOCSIFNETMASK: /* Set the netmask for the interface */
740 740 ret = -EPERM;
741   - if (!capable(CAP_NET_ADMIN))
  741 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
742 742 goto out;
743 743 ret = -EINVAL;
744 744 if (sin->sin_family != AF_INET)
net/ipv4/fib_frontend.c
... ... @@ -488,7 +488,7 @@
488 488 switch (cmd) {
489 489 case SIOCADDRT: /* Add a route */
490 490 case SIOCDELRT: /* Delete a route */
491   - if (!capable(CAP_NET_ADMIN))
  491 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
492 492 return -EPERM;
493 493  
494 494 if (copy_from_user(&rt, arg, sizeof(rt)))
... ... @@ -1064,7 +1064,7 @@
1064 1064 case SIOCADDTUNNEL:
1065 1065 case SIOCCHGTUNNEL:
1066 1066 err = -EPERM;
1067   - if (!capable(CAP_NET_ADMIN))
  1067 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1068 1068 goto done;
1069 1069  
1070 1070 err = -EFAULT;
... ... @@ -1139,7 +1139,7 @@
1139 1139  
1140 1140 case SIOCDELTUNNEL:
1141 1141 err = -EPERM;
1142   - if (!capable(CAP_NET_ADMIN))
  1142 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1143 1143 goto done;
1144 1144  
1145 1145 if (dev == ign->fb_tunnel_dev) {
net/ipv4/ip_options.c
... ... @@ -409,7 +409,7 @@
409 409 optptr[2] += 8;
410 410 break;
411 411 default:
412   - if (!skb && !capable(CAP_NET_RAW)) {
  412 + if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) {
413 413 pp_ptr = optptr + 3;
414 414 goto error;
415 415 }
... ... @@ -445,7 +445,7 @@
445 445 opt->router_alert = optptr - iph;
446 446 break;
447 447 case IPOPT_CIPSO:
448   - if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
  448 + if ((!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) || opt->cipso) {
449 449 pp_ptr = optptr;
450 450 goto error;
451 451 }
... ... @@ -458,7 +458,7 @@
458 458 case IPOPT_SEC:
459 459 case IPOPT_SID:
460 460 default:
461   - if (!skb && !capable(CAP_NET_RAW)) {
  461 + if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) {
462 462 pp_ptr = optptr;
463 463 goto error;
464 464 }
net/ipv4/ip_sockglue.c
... ... @@ -989,13 +989,14 @@
989 989 case IP_IPSEC_POLICY:
990 990 case IP_XFRM_POLICY:
991 991 err = -EPERM;
992   - if (!capable(CAP_NET_ADMIN))
  992 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
993 993 break;
994 994 err = xfrm_user_policy(sk, optname, optval, optlen);
995 995 break;
996 996  
997 997 case IP_TRANSPARENT:
998   - if (!!val && !capable(CAP_NET_RAW) && !capable(CAP_NET_ADMIN)) {
  998 + if (!!val && !ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) &&
  999 + !ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
999 1000 err = -EPERM;
1000 1001 break;
1001 1002 }
... ... @@ -488,7 +488,7 @@
488 488 case SIOCADDTUNNEL:
489 489 case SIOCCHGTUNNEL:
490 490 err = -EPERM;
491   - if (!capable(CAP_NET_ADMIN))
  491 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
492 492 goto done;
493 493  
494 494 err = -EFAULT;
... ... @@ -553,7 +553,7 @@
553 553  
554 554 case SIOCDELTUNNEL:
555 555 err = -EPERM;
556   - if (!capable(CAP_NET_ADMIN))
  556 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
557 557 goto done;
558 558  
559 559 if (dev == ipn->fb_tunnel_dev) {
... ... @@ -691,7 +691,7 @@
691 691 case SIOCADDTUNNEL:
692 692 case SIOCCHGTUNNEL:
693 693 err = -EPERM;
694   - if (!capable(CAP_NET_ADMIN))
  694 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
695 695 goto done;
696 696  
697 697 err = -EFAULT;
... ... @@ -735,7 +735,7 @@
735 735  
736 736 case SIOCDELTUNNEL:
737 737 err = -EPERM;
738   - if (!capable(CAP_NET_ADMIN))
  738 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
739 739 goto done;
740 740  
741 741 if (dev == ipn->fb_tunnel_dev) {
... ... @@ -1213,7 +1213,7 @@
1213 1213  
1214 1214 if (optname != MRT_INIT) {
1215 1215 if (sk != rcu_access_pointer(mrt->mroute_sk) &&
1216   - !capable(CAP_NET_ADMIN))
  1216 + !ns_capable(net->user_ns, CAP_NET_ADMIN))
1217 1217 return -EACCES;
1218 1218 }
1219 1219  
net/ipv4/netfilter/arp_tables.c
... ... @@ -1533,7 +1533,7 @@
1533 1533 {
1534 1534 int ret;
1535 1535  
1536   - if (!capable(CAP_NET_ADMIN))
  1536 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1537 1537 return -EPERM;
1538 1538  
1539 1539 switch (cmd) {
... ... @@ -1677,7 +1677,7 @@
1677 1677 {
1678 1678 int ret;
1679 1679  
1680   - if (!capable(CAP_NET_ADMIN))
  1680 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1681 1681 return -EPERM;
1682 1682  
1683 1683 switch (cmd) {
... ... @@ -1698,7 +1698,7 @@
1698 1698 {
1699 1699 int ret;
1700 1700  
1701   - if (!capable(CAP_NET_ADMIN))
  1701 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1702 1702 return -EPERM;
1703 1703  
1704 1704 switch (cmd) {
... ... @@ -1722,7 +1722,7 @@
1722 1722 {
1723 1723 int ret;
1724 1724  
1725   - if (!capable(CAP_NET_ADMIN))
  1725 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1726 1726 return -EPERM;
1727 1727  
1728 1728 switch (cmd) {
net/ipv4/netfilter/ip_tables.c
... ... @@ -1846,7 +1846,7 @@
1846 1846 {
1847 1847 int ret;
1848 1848  
1849   - if (!capable(CAP_NET_ADMIN))
  1849 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1850 1850 return -EPERM;
1851 1851  
1852 1852 switch (cmd) {
... ... @@ -1961,7 +1961,7 @@
1961 1961 {
1962 1962 int ret;
1963 1963  
1964   - if (!capable(CAP_NET_ADMIN))
  1964 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1965 1965 return -EPERM;
1966 1966  
1967 1967 switch (cmd) {
... ... @@ -1983,7 +1983,7 @@
1983 1983 {
1984 1984 int ret;
1985 1985  
1986   - if (!capable(CAP_NET_ADMIN))
  1986 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1987 1987 return -EPERM;
1988 1988  
1989 1989 switch (cmd) {
... ... @@ -2008,7 +2008,7 @@
2008 2008 {
2009 2009 int ret;
2010 2010  
2011   - if (!capable(CAP_NET_ADMIN))
  2011 + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2012 2012 return -EPERM;
2013 2013  
2014 2014 switch (cmd) {
... ... @@ -2304,7 +2304,7 @@
2304 2304  
2305 2305 static inline bool tcp_can_repair_sock(const struct sock *sk)
2306 2306 {
2307   - return capable(CAP_NET_ADMIN) &&
  2307 + return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) &&
2308 2308 ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED));
2309 2309 }
2310 2310  
... ... @@ -259,7 +259,8 @@
259 259 if (!ca)
260 260 err = -ENOENT;
261 261  
262   - else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || capable(CAP_NET_ADMIN)))
  262 + else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) ||
  263 + ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)))
263 264 err = -EPERM;
264 265  
265 266 else if (!try_module_get(ca->owner))