]> git.hungrycats.org Git - linux/commitdiff
[NET]: Add sock_create_lite()
authorJames Morris <jmorris@redhat.com>
Sat, 8 May 2004 08:05:57 +0000 (01:05 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Sat, 8 May 2004 08:05:57 +0000 (01:05 -0700)
The purpose of this is to allow sockets created by the kernel in this way
to be passed through the LSM socket creation hooks and be labeled and
mediated in the same manner as other sockets.

This patches addresses a class of potential issues with LSMs, where such
sockets will not be labeled correctly (if at all), or mediated during
creation.  Under SELinux, it fixes a specific bug where RPC sockets
created by the kernel during TCP NFS serving are unlabeled.

include/linux/net.h
net/bluetooth/rfcomm/core.c
net/netlink/af_netlink.c
net/socket.c
net/sunrpc/svcsock.c

index 6f7846c15e08e01a5d9b360e0c1df7afb72efc27..3d2cd0cec584599e0418dcb7be46a943882a0e6b 100644 (file)
@@ -151,6 +151,8 @@ extern int       sock_create(int family, int type, int proto,
                                 struct socket **res);
 extern int          sock_create_kern(int family, int type, int proto,
                                      struct socket **res);
+extern int          sock_create_lite(int family, int type, int proto,
+                                     struct socket **res); 
 extern void         sock_release(struct socket *sock);
 extern int          sock_sendmsg(struct socket *sock, struct msghdr *msg,
                                  size_t len);
index 665564beee21bd29b19f63aaeb46756a43a607cf..d9b4ce095b013e47c06933c1882e451e384be164 100644 (file)
@@ -1642,11 +1642,9 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
 
        BT_DBG("session %p", s);
 
-       nsock = sock_alloc();
-       if (!nsock)
+       if (sock_create_lite(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, &nsock))
                return;
-
-       nsock->type = sock->type;
+       
        nsock->ops  = sock->ops;
 
        __module_get(nsock->ops->owner);
index 95b8fbaf313f62dd97a14292ccd178553584fb1c..9a77db793577fcd754091b7b0c7a1caecad07795 100644 (file)
@@ -833,11 +833,9 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len))
        if (unit<0 || unit>=MAX_LINKS)
                return NULL;
 
-       if (!(sock = sock_alloc())) 
+       if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
                return NULL;
 
-       sock->type = SOCK_RAW;
-
        if (netlink_create(sock, unit) < 0) {
                sock_release(sock);
                return NULL;
index f4ef38250280815af1370f8e1f2bf29350c3144e..f8d18942abd95994045028f3626fb0269fe311e0 100644 (file)
@@ -457,7 +457,7 @@ struct socket *sockfd_lookup(int fd, int *err)
  *     NULL is returned.
  */
 
-struct socket *sock_alloc(void)
+static struct socket *sock_alloc(void)
 {
        struct inode * inode;
        struct socket * sock;
@@ -840,6 +840,27 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        return err;
 }
 
+int sock_create_lite(int family, int type, int protocol, struct socket **res)
+{
+       int err;
+       struct socket *sock = NULL;
+       
+       err = security_socket_create(family, type, protocol, 1);
+       if (err)
+               goto out;
+
+       sock = sock_alloc();
+       if (!sock) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       security_socket_post_create(sock, family, type, protocol, 1);
+       sock->type = type;
+out:
+       *res = sock;
+       return err;
+}
 
 /* No kernel lock held - perfect */
 static unsigned int sock_poll(struct file *file, poll_table * wait)
@@ -2001,6 +2022,7 @@ EXPORT_SYMBOL(sock_alloc);
 EXPORT_SYMBOL(sock_alloc_inode);
 EXPORT_SYMBOL(sock_create);
 EXPORT_SYMBOL(sock_create_kern);
+EXPORT_SYMBOL(sock_create_lite);
 EXPORT_SYMBOL(sock_map_fd);
 EXPORT_SYMBOL(sock_recvmsg);
 EXPORT_SYMBOL(sock_register);
index dd199ccbb78a25e5a06b9dfda344cc1a389dbe47..a8ac421d0be1905953eac22dfa7b1cd4c6faff86 100644 (file)
@@ -781,13 +781,15 @@ svc_tcp_accept(struct svc_sock *svsk)
        if (!sock)
                return;
 
-       if (!(newsock = sock_alloc())) {
-               printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name);
+       err = sock_create_lite(PF_INET, SOCK_STREAM, IPPROTO_TCP, &newsock);
+       if (err) {
+               if (err == -ENOMEM)
+                       printk(KERN_WARNING "%s: no more sockets!\n",
+                              serv->sv_name);
                return;
        }
-       dprintk("svc: tcp_accept %p allocated\n", newsock);
 
-       newsock->type = sock->type;
+       dprintk("svc: tcp_accept %p allocated\n", newsock);
        newsock->ops = ops = sock->ops;
 
        clear_bit(SK_CONN, &svsk->sk_flags);