netfilter: conntrack: include kmemleak.h for kmemleak_not_leak()
[linux-2.6-microblaze.git] / net / socket.c
index 67d9d70..54dcb43 100644 (file)
 #include <linux/ipv6_route.h>
 #include <linux/route.h>
 #include <linux/sockios.h>
-#include <linux/atalk.h>
 #include <net/busy_poll.h>
 #include <linux/errqueue.h>
 
@@ -234,7 +233,7 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
        return __put_user(klen, ulen);
 }
 
-static struct kmem_cache *sock_inode_cachep __read_mostly;
+static struct kmem_cache *sock_inode_cachep __ro_after_init;
 
 static struct inode *sock_alloc_inode(struct super_block *sb)
 {
@@ -991,10 +990,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
  *     what to do with it - that's up to the protocol still.
  */
 
-static struct ns_common *get_net_ns(struct ns_common *ns)
+struct ns_common *get_net_ns(struct ns_common *ns)
 {
        return &get_net(container_of(ns, struct net, ns))->ns;
 }
+EXPORT_SYMBOL_GPL(get_net_ns);
 
 static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
@@ -1368,8 +1368,7 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
  *     Create a pair of connected sockets.
  */
 
-SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
-               int __user *, usockvec)
+int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
 {
        struct socket *sock1, *sock2;
        int fd1, fd2, err;
@@ -1454,6 +1453,12 @@ out:
        return err;
 }
 
+SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
+               int __user *, usockvec)
+{
+       return __sys_socketpair(family, type, protocol, usockvec);
+}
+
 /*
  *     Bind a name to a socket. Nothing much to do here since it's
  *     the protocol's responsibility to handle the local address.
@@ -1588,8 +1593,9 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
                goto out_fd;
 
        if (upeer_sockaddr) {
-               if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
-                                         &len, 2) < 0) {
+               len = newsock->ops->getname(newsock,
+                                       (struct sockaddr *)&address, 2);
+               if (len < 0) {
                        err = -ECONNABORTED;
                        goto out_fd;
                }
@@ -1675,12 +1681,12 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  *     name to user space.
  */
 
-SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
-               int __user *, usockaddr_len)
+int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
+                     int __user *usockaddr_len)
 {
        struct socket *sock;
        struct sockaddr_storage address;
-       int len, err, fput_needed;
+       int err, fput_needed;
 
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
@@ -1690,10 +1696,11 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
        if (err)
                goto out_put;
 
-       err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
-       if (err)
+       err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
+       if (err < 0)
                goto out_put;
-       err = move_addr_to_user(&address, len, usockaddr, usockaddr_len);
+        /* "err" is actually length in this case */
+       err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
 
 out_put:
        fput_light(sock->file, fput_needed);
@@ -1701,17 +1708,23 @@ out:
        return err;
 }
 
+SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
+               int __user *, usockaddr_len)
+{
+       return __sys_getsockname(fd, usockaddr, usockaddr_len);
+}
+
 /*
  *     Get the remote address ('name') of a socket object. Move the obtained
  *     name to user space.
  */
 
-SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
-               int __user *, usockaddr_len)
+int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
+                     int __user *usockaddr_len)
 {
        struct socket *sock;
        struct sockaddr_storage address;
-       int len, err, fput_needed;
+       int err, fput_needed;
 
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock != NULL) {
@@ -1721,17 +1734,22 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
                        return err;
                }
 
-               err =
-                   sock->ops->getname(sock, (struct sockaddr *)&address, &len,
-                                      1);
-               if (!err)
-                       err = move_addr_to_user(&address, len, usockaddr,
+               err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
+               if (err >= 0)
+                       /* "err" is actually length in this case */
+                       err = move_addr_to_user(&address, err, usockaddr,
                                                usockaddr_len);
                fput_light(sock->file, fput_needed);
        }
        return err;
 }
 
+SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
+               int __user *, usockaddr_len)
+{
+       return __sys_getpeername(fd, usockaddr, usockaddr_len);
+}
+
 /*
  *     Send a datagram to a given address. We move the address into kernel
  *     space and check the user space data area is readable before invoking
@@ -1861,8 +1879,8 @@ SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  *     to pass the user mode parameter for the protocols to sort out.
  */
 
-SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
-               char __user *, optval, int, optlen)
+static int __sys_setsockopt(int fd, int level, int optname,
+                           char __user *optval, int optlen)
 {
        int err, fput_needed;
        struct socket *sock;
@@ -1890,13 +1908,19 @@ out_put:
        return err;
 }
 
+SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
+               char __user *, optval, int, optlen)
+{
+       return __sys_setsockopt(fd, level, optname, optval, optlen);
+}
+
 /*
  *     Get a socket option. Because we don't know the option lengths we have
  *     to pass a user mode parameter for the protocols to sort out.
  */
 
-SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
-               char __user *, optval, int __user *, optlen)
+static int __sys_getsockopt(int fd, int level, int optname,
+                           char __user *optval, int __user *optlen)
 {
        int err, fput_needed;
        struct socket *sock;
@@ -1921,11 +1945,17 @@ out_put:
        return err;
 }
 
+SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
+               char __user *, optval, int __user *, optlen)
+{
+       return __sys_getsockopt(fd, level, optname, optval, optlen);
+}
+
 /*
  *     Shutdown a socket.
  */
 
-SYSCALL_DEFINE2(shutdown, int, fd, int, how)
+int __sys_shutdown(int fd, int how)
 {
        int err, fput_needed;
        struct socket *sock;
@@ -1940,6 +1970,11 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how)
        return err;
 }
 
+SYSCALL_DEFINE2(shutdown, int, fd, int, how)
+{
+       return __sys_shutdown(fd, how);
+}
+
 /* A couple of helpful macros for getting the address of the 32/64 bit
  * fields which are the same type (int / unsigned) on our platforms.
  */
@@ -2103,12 +2138,16 @@ out_freeiov:
  *     BSD sendmsg interface
  */
 
-long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
+long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
+                  bool forbid_cmsg_compat)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
        struct socket *sock;
 
+       if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
+               return -EINVAL;
+
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -2122,9 +2161,7 @@ out:
 
 SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
 {
-       if (flags & MSG_CMSG_COMPAT)
-               return -EINVAL;
-       return __sys_sendmsg(fd, msg, flags);
+       return __sys_sendmsg(fd, msg, flags, true);
 }
 
 /*
@@ -2132,7 +2169,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int
  */
 
 int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
-                  unsigned int flags)
+                  unsigned int flags, bool forbid_cmsg_compat)
 {
        int fput_needed, err, datagrams;
        struct socket *sock;
@@ -2142,6 +2179,9 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
        struct used_address used_address;
        unsigned int oflags = flags;
 
+       if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
+               return -EINVAL;
+
        if (vlen > UIO_MAXIOV)
                vlen = UIO_MAXIOV;
 
@@ -2198,9 +2238,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
                unsigned int, vlen, unsigned int, flags)
 {
-       if (flags & MSG_CMSG_COMPAT)
-               return -EINVAL;
-       return __sys_sendmmsg(fd, mmsg, vlen, flags);
+       return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
 }
 
 static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
@@ -2273,12 +2311,16 @@ out_freeiov:
  *     BSD recvmsg interface
  */
 
-long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
+long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
+                  bool forbid_cmsg_compat)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
        struct socket *sock;
 
+       if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
+               return -EINVAL;
+
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -2293,9 +2335,7 @@ out:
 SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
                unsigned int, flags)
 {
-       if (flags & MSG_CMSG_COMPAT)
-               return -EINVAL;
-       return __sys_recvmsg(fd, msg, flags);
+       return __sys_recvmsg(fd, msg, flags, true);
 }
 
 /*
@@ -2324,10 +2364,12 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
        if (!sock)
                return err;
 
-       err = sock_error(sock->sk);
-       if (err) {
-               datagrams = err;
-               goto out_put;
+       if (likely(!(flags & MSG_ERRQUEUE))) {
+               err = sock_error(sock->sk);
+               if (err) {
+                       datagrams = err;
+                       goto out_put;
+               }
        }
 
        entry = mmsg;
@@ -2411,9 +2453,9 @@ out_put:
        return datagrams;
 }
 
-SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
-               unsigned int, vlen, unsigned int, flags,
-               struct timespec __user *, timeout)
+static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
+                          unsigned int vlen, unsigned int flags,
+                          struct timespec __user *timeout)
 {
        int datagrams;
        struct timespec timeout_sys;
@@ -2436,6 +2478,13 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
        return datagrams;
 }
 
+SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
+               unsigned int, vlen, unsigned int, flags,
+               struct timespec __user *, timeout)
+{
+       return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout);
+}
+
 #ifdef __ARCH_WANT_SYS_SOCKETCALL
 /* Argument list sizes for sys_socketcall */
 #define AL(x) ((x) * sizeof(unsigned long))
@@ -2500,26 +2549,28 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
                break;
        case SYS_GETSOCKNAME:
                err =
-                   sys_getsockname(a0, (struct sockaddr __user *)a1,
-                                   (int __user *)a[2]);
+                   __sys_getsockname(a0, (struct sockaddr __user *)a1,
+                                     (int __user *)a[2]);
                break;
        case SYS_GETPEERNAME:
                err =
-                   sys_getpeername(a0, (struct sockaddr __user *)a1,
-                                   (int __user *)a[2]);
+                   __sys_getpeername(a0, (struct sockaddr __user *)a1,
+                                     (int __user *)a[2]);
                break;
        case SYS_SOCKETPAIR:
-               err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
+               err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
                break;
        case SYS_SEND:
-               err = sys_send(a0, (void __user *)a1, a[2], a[3]);
+               err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
+                                  NULL, 0);
                break;
        case SYS_SENDTO:
                err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
                                   (struct sockaddr __user *)a[4], a[5]);
                break;
        case SYS_RECV:
-               err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
+               err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
+                                    NULL, NULL);
                break;
        case SYS_RECVFROM:
                err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
@@ -2527,28 +2578,32 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
                                     (int __user *)a[5]);
                break;
        case SYS_SHUTDOWN:
-               err = sys_shutdown(a0, a1);
+               err = __sys_shutdown(a0, a1);
                break;
        case SYS_SETSOCKOPT:
-               err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);
+               err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
+                                      a[4]);
                break;
        case SYS_GETSOCKOPT:
                err =
-                   sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
-                                  (int __user *)a[4]);
+                   __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
+                                    (int __user *)a[4]);
                break;
        case SYS_SENDMSG:
-               err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]);
+               err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
+                                   a[2], true);
                break;
        case SYS_SENDMMSG:
-               err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
+               err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
+                                    a[3], true);
                break;
        case SYS_RECVMSG:
-               err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]);
+               err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
+                                   a[2], true);
                break;
        case SYS_RECVMMSG:
-               err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
-                                  (struct timespec __user *)a[4]);
+               err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2],
+                                     a[3], (struct timespec __user *)a[4]);
                break;
        case SYS_ACCEPT4:
                err = __sys_accept4(a0, (struct sockaddr __user *)a1,
@@ -2623,6 +2678,11 @@ void sock_unregister(int family)
 }
 EXPORT_SYMBOL(sock_unregister);
 
+bool sock_is_registered(int family)
+{
+       return family < NPROTO && rcu_access_pointer(net_families[family]);
+}
+
 static int __init sock_init(void)
 {
        int err;
@@ -3202,17 +3262,15 @@ int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
 }
 EXPORT_SYMBOL(kernel_connect);
 
-int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
-                        int *addrlen)
+int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
 {
-       return sock->ops->getname(sock, addr, addrlen, 0);
+       return sock->ops->getname(sock, addr, 0);
 }
 EXPORT_SYMBOL(kernel_getsockname);
 
-int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
-                        int *addrlen)
+int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
 {
-       return sock->ops->getname(sock, addr, addrlen, 1);
+       return sock->ops->getname(sock, addr, 1);
 }
 EXPORT_SYMBOL(kernel_getpeername);