[NET]: Make socket creation namespace safe.
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 9 Oct 2007 06:24:22 +0000 (23:24 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:49:07 +0000 (16:49 -0700)
This patch passes in the namespace a new socket should be created in
and has the socket code do the appropriate reference counting.  By
virtue of this all socket create methods are touched.  In addition
the socket create methods are modified so that they will fail if
you attempt to create a socket in a non-default network namespace.

Failing if we attempt to create a socket outside of the default
network namespace ensures that as we incrementally make the network stack
network namespace aware we will not export functionality that someone
has not audited and made certain is network namespace safe.
Allowing us to partially enable network namespaces before all of the
exotic protocols are supported.

Any protocol layers I have missed will fail to compile because I now
pass an extra parameter into the socket creation code.

[ Integrated AF_IUCV build fixes from Andrew Morton... -DaveM ]

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
44 files changed:
drivers/net/pppoe.c
drivers/net/pppol2tp.c
drivers/net/pppox.c
include/linux/if_pppox.h
include/linux/net.h
include/net/iucv/af_iucv.h
include/net/llc_conn.h
include/net/sock.h
net/appletalk/ddp.c
net/atm/common.c
net/atm/common.h
net/atm/pvc.c
net/atm/svc.c
net/ax25/af_ax25.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/core/sock.c
net/decnet/af_decnet.c
net/econet/af_econet.c
net/ipv4/af_inet.c
net/ipv6/af_inet6.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/iucv/af_iucv.c
net/key/af_key.c
net/llc/af_llc.c
net/llc/llc_conn.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/packet/af_packet.c
net/rose/af_rose.c
net/rxrpc/af_rxrpc.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/socket.c
net/tipc/socket.c
net/unix/af_unix.c
net/x25/af_x25.c

index ee8ce195c5386ece18a67796840a0f10c98cf2e6..53fcee26d6ae6435014c094d0fd6337d19b265ad 100644 (file)
@@ -477,12 +477,12 @@ static struct proto pppoe_sk_proto = {
  * Initialize a new struct sock.
  *
  **********************************************************************/
-static int pppoe_create(struct socket *sock)
+static int pppoe_create(struct net *net, struct socket *sock)
 {
        int error = -ENOMEM;
        struct sock *sk;
 
-       sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
+       sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
        if (!sk)
                goto out;
 
index 2eb424ba58e53cd982507bf380a688e1194f4388..921d4ef6d14b66d1b66c0c4b606a571cbec82020 100644 (file)
@@ -1411,12 +1411,12 @@ static struct proto pppol2tp_sk_proto = {
 
 /* socket() handler. Initialize a new struct sock.
  */
-static int pppol2tp_create(struct socket *sock)
+static int pppol2tp_create(struct net *net, struct socket *sock)
 {
        int error = -ENOMEM;
        struct sock *sk;
 
-       sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
+       sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
        if (!sk)
                goto out;
 
index 25c52b55c38fb6cb11ddc369ce88f5b527f7cf20..c6898c1fc54d95de595fa990fc7b0977149c796a 100644 (file)
@@ -104,10 +104,13 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
 EXPORT_SYMBOL(pppox_ioctl);
 
-static int pppox_create(struct socket *sock, int protocol)
+static int pppox_create(struct net *net, struct socket *sock, int protocol)
 {
        int rc = -EPROTOTYPE;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (protocol < 0 || protocol > PX_MAX_PROTO)
                goto out;
 
@@ -123,7 +126,7 @@ static int pppox_create(struct socket *sock, int protocol)
            !try_module_get(pppox_protos[protocol]->owner))
                goto out;
 
-       rc = pppox_protos[protocol]->create(sock);
+       rc = pppox_protos[protocol]->create(net, sock);
 
        module_put(pppox_protos[protocol]->owner);
 out:
index 25652545ba6e19683a9efff8172ec83d4b98efd4..43cfc9f0c078279af2da179206ee9691ced5489c 100644 (file)
@@ -172,7 +172,7 @@ static inline struct sock *sk_pppox(struct pppox_sock *po)
 struct module;
 
 struct pppox_proto {
-       int             (*create)(struct socket *sock);
+       int             (*create)(struct net *net, struct socket *sock);
        int             (*ioctl)(struct socket *sock, unsigned int cmd,
                                 unsigned long arg);
        struct module   *owner;
index efc45177b50359cf6cccb218ab75f6a3cb580e0c..c136abce7ef628291325c5ce00a49a1763db6101 100644 (file)
@@ -23,6 +23,7 @@
 
 struct poll_table_struct;
 struct inode;
+struct net;
 
 #define NPROTO         34              /* should be enough for now..   */
 
@@ -169,7 +170,7 @@ struct proto_ops {
 
 struct net_proto_family {
        int             family;
-       int             (*create)(struct socket *sock, int protocol);
+       int             (*create)(struct net *net, struct socket *sock, int protocol);
        struct module   *owner;
 };
 
index b6c468cd7f5ba9fb61f2627fd15a54cd135206af..c661c6fd6fd5d85669097a4a90d08fc41c8b0265 100644 (file)
@@ -78,7 +78,6 @@ static void iucv_sock_destruct(struct sock *sk);
 static void iucv_sock_cleanup_listen(struct sock *parent);
 static void iucv_sock_kill(struct sock *sk);
 static void iucv_sock_close(struct sock *sk);
-static int  iucv_sock_create(struct socket *sock, int proto);
 static int  iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
                        int addr_len);
 static int  iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
index 00730d21b522cc8edc9f1d14de0d73e883833d91..e2374e34989f07d9c39d7bdf30c44266bc1f5ad0 100644 (file)
@@ -93,7 +93,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
        return skb->cb[sizeof(skb->cb) - 1];
 }
 
-extern struct sock *llc_sk_alloc(int family, gfp_t priority,
+extern struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
                                 struct proto *prot);
 extern void llc_sk_free(struct sock *sk);
 
index 9ef8b5fb7936ed42610850188cde4bfcbbc15613..74e1f7d90d731104def058d74196d37f4761a33e 100644 (file)
@@ -56,6 +56,7 @@
 #include <asm/atomic.h>
 #include <net/dst.h>
 #include <net/checksum.h>
+#include <net/net_namespace.h>
 
 /*
  * This structure really needs to be cleaned up.
@@ -776,7 +777,7 @@ extern void FASTCALL(release_sock(struct sock *sk));
                                SINGLE_DEPTH_NESTING)
 #define bh_unlock_sock(__sk)   spin_unlock(&((__sk)->sk_lock.slock))
 
-extern struct sock             *sk_alloc(int family,
+extern struct sock             *sk_alloc(struct net *net, int family,
                                          gfp_t priority,
                                          struct proto *prot, int zero_it);
 extern void                    sk_free(struct sock *sk);
@@ -1005,6 +1006,7 @@ static inline void sock_copy(struct sock *nsk, const struct sock *osk)
 #endif
 
        memcpy(nsk, osk, osk->sk_prot->obj_size);
+       get_net(nsk->sk_net);
 #ifdef CONFIG_SECURITY_NETWORK
        nsk->sk_security = sptr;
        security_sk_clone(osk, nsk);
index 594b59739546ecd5119b7869fb467776d813674e..fd1d52f0970767725a3920281631333444be274c 100644 (file)
@@ -1026,11 +1026,14 @@ static struct proto ddp_proto = {
  * Create a socket. Initialise the socket, blank the addresses
  * set the state.
  */
-static int atalk_create(struct socket *sock, int protocol)
+static int atalk_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        int rc = -ESOCKTNOSUPPORT;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /*
         * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do
         * and gives you the full ELAP frame. Should be handy for CAP 8)
@@ -1038,7 +1041,7 @@ static int atalk_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
                goto out;
        rc = -ENOMEM;
-       sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
+       sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
        if (!sk)
                goto out;
        rc = 0;
index 299ec1eb872a5ae63afcd5a40e76ae661f16f8e8..e166d9e0ffd949f0fe9246a615d7f0a7fbb54b9d 100644 (file)
@@ -125,7 +125,7 @@ static struct proto vcc_proto = {
        .obj_size = sizeof(struct atm_vcc),
 };
 
-int vcc_create(struct socket *sock, int protocol, int family)
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
 {
        struct sock *sk;
        struct atm_vcc *vcc;
@@ -133,7 +133,7 @@ int vcc_create(struct socket *sock, int protocol, int family)
        sock->sk = NULL;
        if (sock->type == SOCK_STREAM)
                return -EINVAL;
-       sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
+       sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, 1);
        if (!sk)
                return -ENOMEM;
        sock_init_data(sock, sk);
index ad78c9e1117d2d3d8c2a9fb5fa995c1539b447cb..16f32c1fa1c9314d8bef751f6185a9173727cc62 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/poll.h> /* for poll_table */
 
 
-int vcc_create(struct socket *sock, int protocol, int family);
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family);
 int vcc_release(struct socket *sock);
 int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
 int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
index 848e6e191cc7179f30c3cfdcfb4007f53c5e8a85..43e8bf5ed0019ceceea7737bf7edbe983c4d8892 100644 (file)
@@ -124,10 +124,13 @@ static const struct proto_ops pvc_proto_ops = {
 };
 
 
-static int pvc_create(struct socket *sock,int protocol)
+static int pvc_create(struct net *net, struct socket *sock,int protocol)
 {
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        sock->ops = &pvc_proto_ops;
-       return vcc_create(sock, protocol, PF_ATMPVC);
+       return vcc_create(net, sock, protocol, PF_ATMPVC);
 }
 
 
index 53d04c7992cf154afb1cc92cb028c02e3ec5aaee..daf9a48a7db04454392fda10fd1f8c142f27b930 100644 (file)
@@ -25,7 +25,7 @@
 #include "signaling.h"
 #include "addr.h"
 
-static int svc_create(struct socket *sock,int protocol);
+static int svc_create(struct net *net, struct socket *sock,int protocol);
 
 /*
  * Note: since all this is still nicely synchronized with the signaling demon,
@@ -326,7 +326,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
 
        lock_sock(sk);
 
-       error = svc_create(newsock,0);
+       error = svc_create(sk->sk_net, newsock,0);
        if (error)
                goto out;
 
@@ -627,12 +627,15 @@ static const struct proto_ops svc_proto_ops = {
 };
 
 
-static int svc_create(struct socket *sock,int protocol)
+static int svc_create(struct net *net, struct socket *sock,int protocol)
 {
        int error;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        sock->ops = &svc_proto_ops;
-       error = vcc_create(sock, protocol, AF_ATMSVC);
+       error = vcc_create(net, sock, protocol, AF_ATMSVC);
        if (error) return error;
        ATM_SD(sock)->local.sas_family = AF_ATMSVC;
        ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
index 1d71f85680b83481c148e3333c9a40ac9e3b6707..def6c42ad165bfde1b82e652d173cb341031e96a 100644 (file)
@@ -780,11 +780,14 @@ static struct proto ax25_proto = {
        .obj_size = sizeof(struct sock),
 };
 
-static int ax25_create(struct socket *sock, int protocol)
+static int ax25_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        ax25_cb *ax25;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        switch (sock->type) {
        case SOCK_DGRAM:
                if (protocol == 0 || protocol == PF_AX25)
@@ -830,7 +833,7 @@ static int ax25_create(struct socket *sock, int protocol)
                return -ESOCKTNOSUPPORT;
        }
 
-       if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
+       if ((sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
                return -ENOMEM;
 
        ax25 = sk->sk_protinfo = ax25_create_cb();
@@ -855,7 +858,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
        struct sock *sk;
        ax25_cb *ax25, *oax25;
 
-       if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+       if ((sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
                return NULL;
 
        if ((ax25 = ax25_create_cb()) == NULL) {
index d942b946ba07efb959686d968677a2ad0faf00ef..1220d8a41eb5ff52d6726250238c975f4cef4e8a 100644 (file)
@@ -95,10 +95,13 @@ int bt_sock_unregister(int proto)
 }
 EXPORT_SYMBOL(bt_sock_unregister);
 
-static int bt_sock_create(struct socket *sock, int proto)
+static int bt_sock_create(struct net *net, struct socket *sock, int proto)
 {
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (proto < 0 || proto >= BT_MAX_PROTO)
                return -EINVAL;
 
@@ -113,7 +116,7 @@ static int bt_sock_create(struct socket *sock, int proto)
        read_lock(&bt_proto_lock);
 
        if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
-               err = bt_proto[proto]->create(sock, proto);
+               err = bt_proto[proto]->create(net, sock, proto);
                module_put(bt_proto[proto]->owner);
        }
 
index 10292e77604612f371e0e26d9b59d446f4897b34..f718965f296c7c3cdd2b46453ffff644fd62fa53 100644 (file)
@@ -204,7 +204,7 @@ static struct proto bnep_proto = {
        .obj_size       = sizeof(struct bt_sock)
 };
 
-static int bnep_sock_create(struct socket *sock, int protocol)
+static int bnep_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -213,7 +213,7 @@ static int bnep_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 19be7861e51ead07db64e1fafb06956cc425e0d1..cf700c20d11eb8915d901914ce3a02e8b546d838 100644 (file)
@@ -195,7 +195,7 @@ static struct proto cmtp_proto = {
        .obj_size       = sizeof(struct bt_sock)
 };
 
-static int cmtp_sock_create(struct socket *sock, int protocol)
+static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -204,7 +204,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 5ccea5fbd2363e3ab1780c39d18f68508432ff0b..43dd6373bff906e56859e36c5c572d772addad3b 100644 (file)
@@ -634,7 +634,7 @@ static struct proto hci_sk_proto = {
        .obj_size       = sizeof(struct hci_pinfo)
 };
 
-static int hci_sock_create(struct socket *sock, int protocol)
+static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -645,7 +645,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &hci_sock_ops;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 0c185257e55bbbe65933a57f6991930b149d2c62..1de2b6fbcac0d442a2d9073e145aa82e3eb9c1d4 100644 (file)
@@ -246,7 +246,7 @@ static struct proto hidp_proto = {
        .obj_size       = sizeof(struct bt_sock)
 };
 
-static int hidp_sock_create(struct socket *sock, int protocol)
+static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -255,7 +255,7 @@ static int hidp_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index c4e4ce4ebb2b1115c6c92b07079fa6be7647c589..36ef27b625db23d19f67c81ae1e1849665d0bc10 100644 (file)
@@ -518,11 +518,11 @@ static struct proto l2cap_proto = {
        .obj_size       = sizeof(struct l2cap_pinfo)
 };
 
-static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
 {
        struct sock *sk;
 
-       sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1);
        if (!sk)
                return NULL;
 
@@ -543,7 +543,7 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
        return sk;
 }
 
-static int l2cap_sock_create(struct socket *sock, int protocol)
+static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -560,7 +560,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &l2cap_sock_ops;
 
-       sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
+       sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
        if (!sk)
                return -ENOMEM;
 
@@ -1425,7 +1425,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
                goto response;
        }
 
-       sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
+       sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC);
        if (!sk)
                goto response;
 
index 30586ab9e8783cad490916c367b1099a14103a85..266b6972667d7713899a22681af5f0a8eef21f73 100644 (file)
@@ -282,12 +282,12 @@ static struct proto rfcomm_proto = {
        .obj_size       = sizeof(struct rfcomm_pinfo)
 };
 
-static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
 {
        struct rfcomm_dlc *d;
        struct sock *sk;
 
-       sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, 1);
        if (!sk)
                return NULL;
 
@@ -323,7 +323,7 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio
        return sk;
 }
 
-static int rfcomm_sock_create(struct socket *sock, int protocol)
+static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -336,7 +336,7 @@ static int rfcomm_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &rfcomm_sock_ops;
 
-       sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
+       sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
        if (!sk)
                return -ENOMEM;
 
@@ -868,7 +868,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
                goto done;
        }
 
-       sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
+       sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
        if (!sk)
                goto done;
 
index 3f5163e725ede1892bdb2912427062f63d881320..65b6fb1c41548c5b508a6b93eb9fe3c0d181857b 100644 (file)
@@ -414,11 +414,11 @@ static struct proto sco_proto = {
        .obj_size       = sizeof(struct sco_pinfo)
 };
 
-static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
 {
        struct sock *sk;
 
-       sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, 1);
        if (!sk)
                return NULL;
 
@@ -439,7 +439,7 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
        return sk;
 }
 
-static int sco_sock_create(struct socket *sock, int protocol)
+static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -452,7 +452,7 @@ static int sco_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &sco_sock_ops;
 
-       sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
+       sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
        if (!sk)
                return -ENOMEM;
 
@@ -807,7 +807,7 @@ static void sco_conn_ready(struct sco_conn *conn)
 
                bh_lock_sock(parent);
 
-               sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
+               sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC);
                if (!sk) {
                        bh_unlock_sock(parent);
                        goto done;
index bbc726a49d87644c6e9d72b65874639387bcf7a2..a31455dc702485b62f846dec01510d29d500ec7d 100644 (file)
@@ -873,7 +873,7 @@ static inline void sock_lock_init(struct sock *sk)
  *     @prot: struct proto associated with this new sock instance
  *     @zero_it: if we should zero the newly allocated sock
  */
-struct sock *sk_alloc(int family, gfp_t priority,
+struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
                      struct proto *prot, int zero_it)
 {
        struct sock *sk = NULL;
@@ -894,6 +894,7 @@ struct sock *sk_alloc(int family, gfp_t priority,
                         */
                        sk->sk_prot = sk->sk_prot_creator = prot;
                        sock_lock_init(sk);
+                       sk->sk_net = get_net(net);
                }
 
                if (security_sk_alloc(sk, family, priority))
@@ -933,6 +934,7 @@ void sk_free(struct sock *sk)
                       __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
 
        security_sk_free(sk);
+       put_net(sk->sk_net);
        if (sk->sk_prot_creator->slab != NULL)
                kmem_cache_free(sk->sk_prot_creator->slab, sk);
        else
@@ -942,7 +944,7 @@ void sk_free(struct sock *sk)
 
 struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
 {
-       struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
+       struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0);
 
        if (newsk != NULL) {
                struct sk_filter *filter;
index 625d5955b8e284a17b84a67b887fe73127fde13f..aca4c4930eb6aaaac698582416026327a20ad175 100644 (file)
@@ -471,10 +471,10 @@ static struct proto dn_proto = {
        .obj_size               = sizeof(struct dn_sock),
 };
 
-static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
+static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
 {
        struct dn_scp *scp;
-       struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
+       struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1);
 
        if  (!sk)
                goto out;
@@ -675,10 +675,13 @@ char *dn_addr2asc(__u16 addr, char *buf)
 
 
 
-static int dn_create(struct socket *sock, int protocol)
+static int dn_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        switch(sock->type) {
                case SOCK_SEQPACKET:
                        if (protocol != DNPROTO_NSP)
@@ -691,7 +694,7 @@ static int dn_create(struct socket *sock, int protocol)
        }
 
 
-       if ((sk = dn_alloc_sock(sock, GFP_KERNEL)) == NULL)
+       if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL)
                return -ENOBUFS;
 
        sk->sk_protocol = protocol;
@@ -1091,7 +1094,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
 
        cb = DN_SKB_CB(skb);
        sk->sk_ack_backlog--;
-       newsk = dn_alloc_sock(newsock, sk->sk_allocation);
+       newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation);
        if (newsk == NULL) {
                release_sock(sk);
                kfree_skb(skb);
index 35c96bcc0f32d445649cc67901814ad11b003ead..a2429dbcb86ee3639e4536754176798f02b2a7ff 100644 (file)
@@ -608,12 +608,15 @@ static struct proto econet_proto = {
  *     Create an Econet socket
  */
 
-static int econet_create(struct socket *sock, int protocol)
+static int econet_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct econet_sock *eo;
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /* Econet only provides datagram services. */
        if (sock->type != SOCK_DGRAM)
                return -ESOCKTNOSUPPORT;
@@ -621,7 +624,7 @@ static int econet_create(struct socket *sock, int protocol)
        sock->state = SS_UNCONNECTED;
 
        err = -ENOBUFS;
-       sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
+       sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto, 1);
        if (sk == NULL)
                goto out;
 
index e68103475cca2a76a349d270d1db72c62132b4c7..110a19edacc817779b112bbdef45e71e6a9e25dd 100644 (file)
@@ -241,7 +241,7 @@ EXPORT_SYMBOL(build_ehash_secret);
  *     Create an inet socket.
  */
 
-static int inet_create(struct socket *sock, int protocol)
+static int inet_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct list_head *p;
@@ -253,6 +253,9 @@ static int inet_create(struct socket *sock, int protocol)
        int try_loading_module = 0;
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (sock->type != SOCK_RAW &&
            sock->type != SOCK_DGRAM &&
            !inet_ehash_secret)
@@ -320,7 +323,7 @@ lookup_protocol:
        BUG_TRAP(answer_prot->slab != NULL);
 
        err = -ENOBUFS;
-       sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
+       sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, 1);
        if (sk == NULL)
                goto out;
 
index b5f96372ad7344b3b815b85a5e29a0b08ac8ad13..21931c86e95b087571bfd342e99c54ea39d0b7d0 100644 (file)
@@ -81,7 +81,7 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
        return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
 }
 
-static int inet6_create(struct socket *sock, int protocol)
+static int inet6_create(struct net *net, struct socket *sock, int protocol)
 {
        struct inet_sock *inet;
        struct ipv6_pinfo *np;
@@ -94,6 +94,9 @@ static int inet6_create(struct socket *sock, int protocol)
        int try_loading_module = 0;
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (sock->type != SOCK_RAW &&
            sock->type != SOCK_DGRAM &&
            !inet_ehash_secret)
@@ -159,7 +162,7 @@ lookup_protocol:
        BUG_TRAP(answer_prot->slab != NULL);
 
        err = -ENOBUFS;
-       sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
+       sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, 1);
        if (sk == NULL)
                goto out;
 
index 8400525177ab4c837df020947bbd74133487023f..ee28babad22782c782cbf104ae314c3b47b5dd66 100644 (file)
@@ -1360,11 +1360,14 @@ static struct proto ipx_proto = {
        .obj_size = sizeof(struct ipx_sock),
 };
 
-static int ipx_create(struct socket *sock, int protocol)
+static int ipx_create(struct net *net, struct socket *sock, int protocol)
 {
        int rc = -ESOCKTNOSUPPORT;
        struct sock *sk;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /*
         * SPX support is not anymore in the kernel sources. If you want to
         * ressurrect it, completing it and making it understand shared skbs,
@@ -1375,7 +1378,7 @@ static int ipx_create(struct socket *sock, int protocol)
                goto out;
 
        rc = -ENOMEM;
-       sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
+       sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, 1);
        if (!sk)
                goto out;
 #ifdef IPX_REFCNT_DEBUG
index c80949a719239255061075e158bc70dd43e015ab..0328ae2654f43333fc09980368dec290641d24fb 100644 (file)
@@ -60,7 +60,7 @@
 
 #include <net/irda/af_irda.h>
 
-static int irda_create(struct socket *sock, int protocol);
+static int irda_create(struct net *net, struct socket *sock, int protocol);
 
 static const struct proto_ops irda_stream_ops;
 static const struct proto_ops irda_seqpacket_ops;
@@ -831,7 +831,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
-       err = irda_create(newsock, sk->sk_protocol);
+       err = irda_create(sk->sk_net, newsock, sk->sk_protocol);
        if (err)
                return err;
 
@@ -1057,13 +1057,16 @@ static struct proto irda_proto = {
  *    Create IrDA socket
  *
  */
-static int irda_create(struct socket *sock, int protocol)
+static int irda_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct irda_sock *self;
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /* Check for valid socket type */
        switch (sock->type) {
        case SOCK_STREAM:     /* For TTP connections with SAR disabled */
@@ -1075,7 +1078,7 @@ static int irda_create(struct socket *sock, int protocol)
        }
 
        /* Allocate networking socket */
-       sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
+       sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
        if (sk == NULL)
                return -ENOMEM;
 
index 53ae14c35f70865eb4a224e9b51425d8add8d19a..53668585e947720cbfced1ebb02c82c61ec62e13 100644 (file)
@@ -213,7 +213,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
 {
        struct sock *sk;
 
-       sk = sk_alloc(PF_IUCV, prio, &iucv_proto, 1);
+       sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto, 1);
        if (!sk)
                return NULL;
 
@@ -240,7 +240,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
 }
 
 /* Create an IUCV socket */
-static int iucv_sock_create(struct socket *sock, int protocol)
+static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
index 5b802bbb856e4f08b983284cad7f7e6dded1728c..ff5c3d03005e4603b0748d003aff2b097ca675c3 100644 (file)
@@ -136,11 +136,14 @@ static struct proto key_proto = {
        .obj_size = sizeof(struct pfkey_sock),
 };
 
-static int pfkey_create(struct socket *sock, int protocol)
+static int pfkey_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
        if (sock->type != SOCK_RAW)
@@ -149,7 +152,7 @@ static int pfkey_create(struct socket *sock, int protocol)
                return -EPROTONOSUPPORT;
 
        err = -ENOMEM;
-       sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
+       sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, 1);
        if (sk == NULL)
                goto out;
 
index 6b8a103cf9e66f198984fed8656ddacf9781718a..b48244156e756ec4a396fea765eec7a8a71facd6 100644 (file)
@@ -150,14 +150,17 @@ static struct proto llc_proto = {
  *     socket type we have available.
  *     Returns 0 upon success, negative upon failure.
  */
-static int llc_ui_create(struct socket *sock, int protocol)
+static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        int rc = -ESOCKTNOSUPPORT;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
                rc = -ENOMEM;
-               sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
+               sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto);
                if (sk) {
                        rc = 0;
                        llc_ui_sk_init(sock, sk);
index 3b8cfbe029a74ba8d47fb24bd1d1aad8f952d351..8ebc2769dfdabc88c288468002148d5c974fd68f 100644 (file)
@@ -700,7 +700,7 @@ static struct sock *llc_create_incoming_sock(struct sock *sk,
                                             struct llc_addr *saddr,
                                             struct llc_addr *daddr)
 {
-       struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
+       struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC,
                                          sk->sk_prot);
        struct llc_sock *newllc, *llc = llc_sk(sk);
 
@@ -867,9 +867,9 @@ static void llc_sk_init(struct sock* sk)
  *     Allocates a LLC sock and initializes it. Returns the new LLC sock
  *     or %NULL if there's no memory available for one
  */
-struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot)
+struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot)
 {
-       struct sock *sk = sk_alloc(family, priority, prot, 1);
+       struct sock *sk = sk_alloc(net, family, priority, prot, 1);
 
        if (!sk)
                goto out;
index 3982f13dab17954db40368b37d6cf37ea19e2c96..406a493300d8ea0578f748103aa70a8d8a59efc8 100644 (file)
@@ -384,15 +384,15 @@ static struct proto netlink_proto = {
        .obj_size = sizeof(struct netlink_sock),
 };
 
-static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
-                           int protocol)
+static int __netlink_create(struct net *net, struct socket *sock,
+                           struct mutex *cb_mutex, int protocol)
 {
        struct sock *sk;
        struct netlink_sock *nlk;
 
        sock->ops = &netlink_ops;
 
-       sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
+       sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
        if (!sk)
                return -ENOMEM;
 
@@ -412,13 +412,16 @@ static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
        return 0;
 }
 
-static int netlink_create(struct socket *sock, int protocol)
+static int netlink_create(struct net *net, struct socket *sock, int protocol)
 {
        struct module *module = NULL;
        struct mutex *cb_mutex;
        struct netlink_sock *nlk;
        int err = 0;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        sock->state = SS_UNCONNECTED;
 
        if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
@@ -441,7 +444,7 @@ static int netlink_create(struct socket *sock, int protocol)
        cb_mutex = nl_table[protocol].cb_mutex;
        netlink_unlock_table();
 
-       if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0)
+       if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0)
                goto out_module;
 
        nlk = nlk_sk(sock->sk);
@@ -1318,7 +1321,7 @@ netlink_kernel_create(int unit, unsigned int groups,
        if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
                return NULL;
 
-       if (__netlink_create(sock, cb_mutex, unit) < 0)
+       if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
                goto out_sock_release;
 
        if (groups < 32)
index 15c8a92bd7193bc6d19d386fadeb6a23815f2c51..e969d1bc765c1d673d5c1eba1c1f23b9bed976c4 100644 (file)
@@ -409,15 +409,18 @@ static struct proto nr_proto = {
        .obj_size = sizeof(struct nr_sock),
 };
 
-static int nr_create(struct socket *sock, int protocol)
+static int nr_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct nr_sock *nr;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (sock->type != SOCK_SEQPACKET || protocol != 0)
                return -ESOCKTNOSUPPORT;
 
-       if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
+       if ((sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
                return -ENOMEM;
 
        nr = nr_sk(sk);
@@ -459,7 +462,7 @@ static struct sock *nr_make_new(struct sock *osk)
        if (osk->sk_type != SOCK_SEQPACKET)
                return NULL;
 
-       if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+       if ((sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
                return NULL;
 
        nr = nr_sk(sk);
index 56502292f24c99677963cfb6a774539081d41a19..766b5faaed21aa88de5d0a675a5186505276e7c2 100644 (file)
@@ -977,13 +977,16 @@ static struct proto packet_proto = {
  *     Create a packet of type SOCK_PACKET.
  */
 
-static int packet_create(struct socket *sock, int protocol)
+static int packet_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct packet_sock *po;
        __be16 proto = (__force __be16)protocol; /* weird, but documented */
        int err;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (!capable(CAP_NET_RAW))
                return -EPERM;
        if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
@@ -993,7 +996,7 @@ static int packet_create(struct socket *sock, int protocol)
        sock->state = SS_UNCONNECTED;
 
        err = -ENOBUFS;
-       sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
+       sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1);
        if (sk == NULL)
                goto out;
 
index 48319f7991ac644ce04f87f9ad8d672f9a162ac0..67e06ab7f85458e356a567030669f6a5c6d3c9a7 100644 (file)
@@ -499,15 +499,18 @@ static struct proto rose_proto = {
        .obj_size = sizeof(struct rose_sock),
 };
 
-static int rose_create(struct socket *sock, int protocol)
+static int rose_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct rose_sock *rose;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (sock->type != SOCK_SEQPACKET || protocol != 0)
                return -ESOCKTNOSUPPORT;
 
-       if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+       if ((sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
                return -ENOMEM;
 
        rose = rose_sk(sk);
@@ -545,7 +548,7 @@ static struct sock *rose_make_new(struct sock *osk)
        if (osk->sk_type != SOCK_SEQPACKET)
                return NULL;
 
-       if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+       if ((sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
                return NULL;
 
        rose = rose_sk(sk);
index 122d55d992e121ab2f8b24bc0d2e1668f55aa59e..0803f305ed081c09d29d5c568ada9df7aeb27ee4 100644 (file)
@@ -606,13 +606,16 @@ static unsigned int rxrpc_poll(struct file *file, struct socket *sock,
 /*
  * create an RxRPC socket
  */
-static int rxrpc_create(struct socket *sock, int protocol)
+static int rxrpc_create(struct net *net, struct socket *sock, int protocol)
 {
        struct rxrpc_sock *rx;
        struct sock *sk;
 
        _enter("%p,%d", sock, protocol);
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /* we support transport protocol UDP only */
        if (protocol != PF_INET)
                return -EPROTONOSUPPORT;
@@ -623,7 +626,7 @@ static int rxrpc_create(struct socket *sock, int protocol)
        sock->ops = &rxrpc_rpc_ops;
        sock->state = SS_UNCONNECTED;
 
-       sk = sk_alloc(PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
+       sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index ec29b97dbab96514a9e1faa5d80c727ac35311a9..ddeb4882ec7519f0903929e4d4cbaa87f9d6bc96 100644 (file)
@@ -631,7 +631,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
        struct sctp6_sock *newsctp6sk;
 
-       newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
+       newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
        if (!newsk)
                goto out;
 
index 30929e3ca05a76f48920d8b530431e8b4e79d4a8..af67c839ef98410c55c5c6c8018ad41fc8f6ad64 100644 (file)
@@ -552,7 +552,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
 {
        struct inet_sock *inet = inet_sk(sk);
        struct inet_sock *newinet;
-       struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
+       struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, sk->sk_prot, 1);
 
        if (!newsk)
                goto out;
index b09eb9036a17a3563e9ad5ca08a1734b86aa0df5..a714c6d4e4a16c798c8b83d849469ee092bf8e01 100644 (file)
@@ -84,6 +84,7 @@
 #include <linux/kmod.h>
 #include <linux/audit.h>
 #include <linux/wireless.h>
+#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -1071,7 +1072,7 @@ call_kill:
        return 0;
 }
 
-static int __sock_create(int family, int type, int protocol,
+static int __sock_create(struct net *net, int family, int type, int protocol,
                         struct socket **res, int kern)
 {
        int err;
@@ -1147,7 +1148,7 @@ static int __sock_create(int family, int type, int protocol,
        /* Now protected by module ref count */
        rcu_read_unlock();
 
-       err = pf->create(sock, protocol);
+       err = pf->create(net, sock, protocol);
        if (err < 0)
                goto out_module_put;
 
@@ -1186,12 +1187,12 @@ out_release:
 
 int sock_create(int family, int type, int protocol, struct socket **res)
 {
-       return __sock_create(family, type, protocol, res, 0);
+       return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
 }
 
 int sock_create_kern(int family, int type, int protocol, struct socket **res)
 {
-       return __sock_create(family, type, protocol, res, 1);
+       return __sock_create(&init_net, family, type, protocol, res, 1);
 }
 
 asmlinkage long sys_socket(int family, int type, int protocol)
index 84110172031ef6bfa69716a90ca4bbda6b48e3f4..e36b4b5a5222320644fd1d7fe35c06bfe982e7f0 100644 (file)
@@ -162,13 +162,16 @@ static void advance_queue(struct tipc_sock *tsock)
  *
  * Returns 0 on success, errno otherwise
  */
-static int tipc_create(struct socket *sock, int protocol)
+static int tipc_create(struct net *net, struct socket *sock, int protocol)
 {
        struct tipc_sock *tsock;
        struct tipc_port *port;
        struct sock *sk;
        u32 ref;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (unlikely(protocol != 0))
                return -EPROTONOSUPPORT;
 
@@ -198,7 +201,7 @@ static int tipc_create(struct socket *sock, int protocol)
                return -EPROTOTYPE;
        }
 
-       sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
+       sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
        if (!sk) {
                tipc_deleteport(ref);
                return -ENOMEM;
@@ -1372,7 +1375,7 @@ static int accept(struct socket *sock, struct socket *newsock, int flags)
        }
        buf = skb_peek(&sock->sk->sk_receive_queue);
 
-       res = tipc_create(newsock, 0);
+       res = tipc_create(sock->sk->sk_net, newsock, 0);
        if (!res) {
                struct tipc_sock *new_tsock = tipc_sk(newsock->sk);
                struct tipc_portid id;
index 2386090c3a16ef4469a9dd0d843e92bb73d882e6..10e73122c34c0bd23cb7a5bff61bb62c131cb4e4 100644 (file)
@@ -594,7 +594,7 @@ static struct proto unix_proto = {
  */
 static struct lock_class_key af_unix_sk_receive_queue_lock_key;
 
-static struct sock * unix_create1(struct socket *sock)
+static struct sock * unix_create1(struct net *net, struct socket *sock)
 {
        struct sock *sk = NULL;
        struct unix_sock *u;
@@ -602,7 +602,7 @@ static struct sock * unix_create1(struct socket *sock)
        if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
                goto out;
 
-       sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
+       sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, 1);
        if (!sk)
                goto out;
 
@@ -628,8 +628,11 @@ out:
        return sk;
 }
 
-static int unix_create(struct socket *sock, int protocol)
+static int unix_create(struct net *net, struct socket *sock, int protocol)
 {
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (protocol && protocol != PF_UNIX)
                return -EPROTONOSUPPORT;
 
@@ -655,7 +658,7 @@ static int unix_create(struct socket *sock, int protocol)
                return -ESOCKTNOSUPPORT;
        }
 
-       return unix_create1(sock) ? 0 : -ENOMEM;
+       return unix_create1(net, sock) ? 0 : -ENOMEM;
 }
 
 static int unix_release(struct socket *sock)
@@ -1039,7 +1042,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
        err = -ENOMEM;
 
        /* create new sock for complete connection */
-       newsk = unix_create1(NULL);
+       newsk = unix_create1(sk->sk_net, NULL);
        if (newsk == NULL)
                goto out;
 
index 479927cb45cacd3c8f3f797a916bb51edf0cbbfc..2e9931571a4d29f092e07725465ec3a28563981e 100644 (file)
@@ -466,10 +466,10 @@ static struct proto x25_proto = {
        .obj_size = sizeof(struct x25_sock),
 };
 
-static struct sock *x25_alloc_socket(void)
+static struct sock *x25_alloc_socket(struct net *net)
 {
        struct x25_sock *x25;
-       struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
+       struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, 1);
 
        if (!sk)
                goto out;
@@ -485,17 +485,20 @@ out:
        return sk;
 }
 
-static int x25_create(struct socket *sock, int protocol)
+static int x25_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct x25_sock *x25;
        int rc = -ESOCKTNOSUPPORT;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        if (sock->type != SOCK_SEQPACKET || protocol)
                goto out;
 
        rc = -ENOMEM;
-       if ((sk = x25_alloc_socket()) == NULL)
+       if ((sk = x25_alloc_socket(net)) == NULL)
                goto out;
 
        x25 = x25_sk(sk);
@@ -543,7 +546,7 @@ static struct sock *x25_make_new(struct sock *osk)
        if (osk->sk_type != SOCK_SEQPACKET)
                goto out;
 
-       if ((sk = x25_alloc_socket()) == NULL)
+       if ((sk = x25_alloc_socket(osk->sk_net)) == NULL)
                goto out;
 
        x25 = x25_sk(sk);