net: Allow userns root to control llc, netfilter, netlink, packet, and xfrm
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 16 Nov 2012 03:03:07 +0000 (03:03 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 19 Nov 2012 01:32:45 +0000 (20:32 -0500)
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>
net/key/af_key.c
net/llc/af_llc.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nfnetlink.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/xfrm/xfrm_user.c

index 08897a3c7ec764550d518777811fa8e3179a9492..5b426a6465447f954a4b4728f72a6c00966c91ee 100644 (file)
@@ -141,7 +141,7 @@ static int pfkey_create(struct net *net, struct socket *sock, int protocol,
        struct sock *sk;
        int err;
 
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                return -EPERM;
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
index c2190005a11410e2f95141fb841dadc051157a8b..88709882c4641f7d147fbeaa9f48323cfc8637eb 100644 (file)
@@ -160,7 +160,7 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol,
        struct sock *sk;
        int rc = -ESOCKTNOSUPPORT;
 
-       if (!capable(CAP_NET_RAW))
+       if (!ns_capable(net->user_ns, CAP_NET_RAW))
                return -EPERM;
 
        if (!net_eq(net, &init_net))
index 778465f217fa975c39af6fb3d7429214dbfe2a51..fed899f600b2fdcab31604dfd09f52f32581d89f 100644 (file)
@@ -1643,7 +1643,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
        void *data;
        int copylen = *len, ret = 0;
 
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
                return -EPERM;
        if (optval != SO_IP_SET)
                return -EBADF;
index c6cebd560936b6e70737d9e03814e2fe16fb9a45..ec664cbb119f658991fd1e18134305ec08b4d5d8 100644 (file)
@@ -2339,7 +2339,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
        struct ip_vs_dest_user_kern udest;
        struct netns_ipvs *ipvs = net_ipvs(net);
 
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
                return -EPERM;
 
        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)
        struct netns_ipvs *ipvs = net_ipvs(net);
 
        BUG_ON(!net);
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
                return -EPERM;
 
        if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX)
index ffb92c03a358a8ce64c9e824a09db72a823b76d8..58a09b7c3f6d50b4cf95a4c139d637a225421aae 100644 (file)
@@ -138,7 +138,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        const struct nfnetlink_subsystem *ss;
        int type, err;
 
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                return -EPERM;
 
        /* All the messages must at least contain nfgenmsg */
index 4da797fa5ec57641a0fa70b5dd1e6e517884fad4..c8a1eb6eca2dea3597ba9c96a01b84656bad5700 100644 (file)
@@ -612,7 +612,7 @@ retry:
 static inline int netlink_capable(const struct socket *sock, unsigned int flag)
 {
        return (nl_table[sock->sk->sk_protocol].flags & flag) ||
-              capable(CAP_NET_ADMIN);
+               ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN);
 }
 
 static void
index f262dbfc7f0684c34f44bc39ea7615aa8e82e3f7..e639645e8fec8ca365c8fc1bc4fb3650db04b5f4 100644 (file)
@@ -2504,7 +2504,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
        __be16 proto = (__force __be16)protocol; /* weird, but documented */
        int err;
 
-       if (!capable(CAP_NET_RAW))
+       if (!ns_capable(net->user_ns, CAP_NET_RAW))
                return -EPERM;
        if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
            sock->type != SOCK_PACKET)
index 421f9844433519eac0c41e24265d2be9c1155b49..eb872b2e366e1209993efe470bed7f614a299098 100644 (file)
@@ -2349,7 +2349,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        link = &xfrm_dispatch[type];
 
        /* All operations require privileges, even GET */
-       if (!capable(CAP_NET_ADMIN))
+       if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                return -EPERM;
 
        if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||