disable some mediatekl custom warnings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / socket.c
index 9ff6366fee13d1bb2e889fcf5726b39299feaf8a..0d716c943918334ae7ba285265f47ee138b76d55 100644 (file)
@@ -97,6 +97,7 @@
 #include <net/cls_cgroup.h>
 
 #include <net/sock.h>
+#include <net/inet_sock.h>
 #include <linux/netfilter.h>
 
 #include <linux/if_tun.h>
@@ -215,12 +216,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
        int err;
        int len;
 
+       BUG_ON(klen > sizeof(struct sockaddr_storage));
        err = get_user(len, ulen);
        if (err)
                return err;
        if (len > klen)
                len = klen;
-       if (len < 0 || len > sizeof(struct sockaddr_storage))
+       if (len < 0)
                return -EINVAL;
        if (len) {
                if (audit_sockaddr(klen, kaddr))
@@ -586,7 +588,7 @@ void sock_release(struct socket *sock)
        }
 
        if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
-               printk(KERN_ERR "sock_release: fasync list not empty!\n");
+               printk(KERN_ERR "[mtk_net][socket]sock_release: fasync list not empty!\n");
 
        if (test_bit(SOCK_EXTERNALLY_ALLOCATED, &sock->flags))
                return;
@@ -1160,7 +1162,22 @@ static int sock_mmap(struct file *file, struct vm_area_struct *vma)
 
 static int sock_close(struct inode *inode, struct file *filp)
 {
+       /*
+        *      It was possible the inode is NULL we were
+        *      closing an unfinished socket.
+        */
+
+       if (!inode) {
+               #ifdef CONFIG_MTK_NET_LOGGING 
+               printk(KERN_DEBUG "[mtk_net][socket]sock_close: NULL inode\n");
+               #endif
+               return 0;
+       }
+    #ifdef CONFIG_MTK_NET_LOGGING 
+       printk(KERN_INFO "[mtk_net][socekt]socket_close[%lu] \n",inode->i_ino); 
+       #endif
        sock_release(SOCKET_I(inode));
+       
        return 0;
 }
 
@@ -1256,8 +1273,10 @@ int __sock_create(struct net *net, int family, int type, int protocol,
                static int warned;
                if (!warned) {
                        warned = 1;
-                       printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)\n",
+                       #ifdef CONFIG_MTK_NET_LOGGING 
+                       printk(KERN_INFO "[mtk_net][socket]%s uses obsolete (PF_INET,SOCK_PACKET)\n",
                               current->comm);
+                       #endif
                }
                family = PF_PACKET;
        }
@@ -1387,6 +1406,19 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
 
 out:
        /* It may be already another descriptor 8) Not kernel problem. */
+
+       if((retval >= 0)&& sock && SOCK_INODE(sock) )
+       {
+          #ifdef CONFIG_MTK_NET_LOGGING 
+          printk(KERN_INFO "[mtk_net][socket]socket_create[%lu]:fd=%d \n",SOCK_INODE(sock)->i_ino,retval);
+          #endif               
+       }
+        else
+        {
+               #ifdef CONFIG_MTK_NET_LOGGING   
+          printk(KERN_INFO "[mtk_net][socket]socket_create:fd=%d \n",retval); 
+          #endif
+        }
        return retval;
 
 out_release:
@@ -1397,7 +1429,6 @@ out_release:
 /*
  *     Create a pair of connected sockets.
  */
-
 SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
                int __user *, usockvec)
 {
@@ -1472,10 +1503,22 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
        if (!err)
                err = put_user(fd2, &usockvec[1]);
        if (!err)
+        {
+            if(sock1 && SOCK_INODE(sock1) && sock2&& SOCK_INODE(sock2) )
+            {
+                       #ifdef CONFIG_MTK_NET_LOGGING 
+                   printk(KERN_INFO "[mtk_net][socket]socketpair:fd1[%lu]=%d, fd2[%lu]=%d \n", SOCK_INODE(sock1)->i_ino,fd1,SOCK_INODE(sock2)->i_ino,fd2);
+                   #endif             
+            }
+         
                return 0;
+        }
 
        sys_close(fd2);
        sys_close(fd1);
+       #ifdef CONFIG_MTK_NET_LOGGING 
+       printk(KERN_INFO "[mtk_net][socket]socketpair fail1: %d \n", err);
+       #endif
        return err;
 
 out_release_both:
@@ -1483,6 +1526,9 @@ out_release_both:
 out_release_1:
        sock_release(sock1);
 out:
+       #ifdef CONFIG_MTK_NET_LOGGING 
+    printk(KERN_INFO "[mtk_net][socket]socketpair fail2: %d \n", err);
+    #endif
        return err;
 }
 
@@ -1503,6 +1549,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock) {
                err = move_addr_to_kernel(umyaddr, addrlen, &address);
+
                if (err >= 0) {
                        err = security_socket_bind(sock,
                                                   (struct sockaddr *)&address,
@@ -1511,6 +1558,13 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
                                err = sock->ops->bind(sock,
                                                      (struct sockaddr *)
                                                      &address, addrlen);
+                       
+      #ifdef CONFIG_MTK_NET_LOGGING 
+                   if((((struct sockaddr_in *)&address)->sin_family) != AF_UNIX)
+                       {
+                                printk(KERN_WARNING "[mtk_net][socket] bind addr->sin_port:%d,err:%d \n",htons(((struct sockaddr_in *)&address)->sin_port),err);
+          }
+        #endif               
                }
                fput_light(sock->file, fput_needed);
        }
@@ -1555,7 +1609,6 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  *     status to recvmsg. We need to add that support in a way thats
  *     clean when we restucture accept also.
  */
-
 SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
                int __user *, upeer_addrlen, int, flags)
 {
@@ -1630,6 +1683,13 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
 out_put:
        fput_light(sock->file, fput_needed);
 out:
+        if( (err>=0)&& newsock && SOCK_INODE(newsock) )
+      {
+               #ifdef CONFIG_MTK_NET_LOGGING 
+               printk(KERN_INFO "[mtk_net][socket]socket_accept:fd=%d \n",err);
+               #endif
+           }  
+           
        return err;
 out_fd:
        fput(newfile);
@@ -1763,6 +1823,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
 
        if (len > INT_MAX)
                len = INT_MAX;
+       if (unlikely(!access_ok(VERIFY_READ, buff, len)))
+               return -EFAULT;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -1822,6 +1884,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
 
        if (size > INT_MAX)
                size = INT_MAX;
+       if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size)))
+               return -EFAULT;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -1832,8 +1896,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        msg.msg_iov = &iov;
        iov.iov_len = size;
        iov.iov_base = ubuf;
-       msg.msg_name = (struct sockaddr *)&address;
-       msg.msg_namelen = sizeof(address);
+       /* Save some cycles and don't copy the address if not needed */
+       msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg.msg_namelen = 0;
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = sock_recvmsg(sock, &msg, size, flags);
@@ -1956,7 +2022,21 @@ struct used_address {
        unsigned int name_len;
 };
 
-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+static int copy_msghdr_from_user(struct msghdr *kmsg,
+                                struct msghdr __user *umsg)
+{
+       if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
+               return -EFAULT;
+
+       if (kmsg->msg_namelen < 0)
+               return -EINVAL;
+
+       if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+               kmsg->msg_namelen = sizeof(struct sockaddr_storage);
+       return 0;
+}
+
+static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags,
                         struct used_address *used_address)
 {
@@ -1974,8 +2054,11 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
        if (MSG_CMSG_COMPAT & flags) {
                if (get_compat_msghdr(msg_sys, msg_compat))
                        return -EFAULT;
-       } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
-               return -EFAULT;
+       } else {
+               err = copy_msghdr_from_user(msg_sys, msg);
+               if (err)
+                       return err;
+       }
 
        if (msg_sys->msg_iovlen > UIO_FASTIOV) {
                err = -EMSGSIZE;
@@ -2071,26 +2154,30 @@ out:
  *     BSD sendmsg interface
  */
 
-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
        struct socket *sock;
 
-       if (flags & MSG_CMSG_COMPAT)
-               return -EINVAL;
-
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
+       err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_sendmsg(fd, msg, flags);
+}
+
 /*
  *     Linux sendmmsg interface
  */
@@ -2121,15 +2208,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 
        while (datagrams < vlen) {
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2158,7 +2246,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
        return __sys_sendmmsg(fd, mmsg, vlen, flags);
 }
 
-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags, int nosec)
 {
        struct compat_msghdr __user *msg_compat =
@@ -2178,8 +2266,11 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
        if (MSG_CMSG_COMPAT & flags) {
                if (get_compat_msghdr(msg_sys, msg_compat))
                        return -EFAULT;
-       } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
-               return -EFAULT;
+       } else {
+               err = copy_msghdr_from_user(msg_sys, msg);
+               if (err)
+                       return err;
+       }
 
        if (msg_sys->msg_iovlen > UIO_FASTIOV) {
                err = -EMSGSIZE;
@@ -2192,16 +2283,14 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                        goto out;
        }
 
-       /*
-        *      Save the user-mode address (verify_iovec will change the
-        *      kernel msghdr to use the kernel address space)
+       /* Save the user-mode address (verify_iovec will change the
+        * kernel msghdr to use the kernel address space)
         */
-
        uaddr = (__force void __user *)msg_sys->msg_name;
        uaddr_len = COMPAT_NAMELEN(msg);
-       if (MSG_CMSG_COMPAT & flags) {
+       if (MSG_CMSG_COMPAT & flags)
                err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-       else
+       else
                err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
        if (err < 0)
                goto out_freeiov;
@@ -2210,6 +2299,9 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
        cmsg_ptr = (unsigned long)msg_sys->msg_control;
        msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
 
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg_sys->msg_namelen = 0;
+
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
@@ -2250,27 +2342,31 @@ out:
  *     BSD recvmsg interface
  */
 
-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
-               unsigned int, flags)
+long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
        struct socket *sock;
 
-       if (flags & MSG_CMSG_COMPAT)
-               return -EINVAL;
-
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
+       err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
+               unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_recvmsg(fd, msg, flags);
+}
+
 /*
  *     Linux recvmmsg interface
  */
@@ -2308,17 +2404,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                 * No need to ask LSM for more than the first datagram.
                 */
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2351,13 +2448,14 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                        break;
        }
 
-out_put:
-       fput_light(sock->file, fput_needed);
-
        if (err == 0)
-               return datagrams;
+               goto out_put;           
+
+       if (datagrams == 0) {
+               datagrams = err;
+               goto out_put;
+       }
 
-       if (datagrams != 0) {
                /*
                 * We may return less entries than requested (vlen) if the
                 * sock is non block and there aren't enough datagrams...
@@ -2372,10 +2470,10 @@ out_put:
                        sock->sk->sk_err = -err;
                }
 
-               return datagrams;
-       }
+out_put:
+       fput_light(sock->file, fput_needed);
 
-       return err;
+       return datagrams;
 }
 
 SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
@@ -2505,31 +2603,15 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
                                   (int __user *)a[4]);
                break;
        case SYS_SENDMSG:
-               if (a[2] & MSG_CMSG_COMPAT) {
-                       err = -EINVAL;
-                       break;
-               }
                err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
                break;
        case SYS_SENDMMSG:
-               if (a[3] & MSG_CMSG_COMPAT) {
-                       err = -EINVAL;
-                       break;
-               }
                err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
                break;
        case SYS_RECVMSG:
-               if (a[2] & MSG_CMSG_COMPAT) {
-                       err = -EINVAL;
-                       break;
-               }
                err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
                break;
        case SYS_RECVMMSG:
-               if (a[3] & MSG_CMSG_COMPAT) {
-                       err = -EINVAL;
-                       break;
-               }
                err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
                                   (struct timespec __user *)a[4]);
                break;
@@ -2560,7 +2642,7 @@ int sock_register(const struct net_proto_family *ops)
        int err;
 
        if (ops->family >= NPROTO) {
-               printk(KERN_CRIT "protocol %d >= NPROTO(%d)\n", ops->family,
+               printk(KERN_CRIT "[mtk_net][sock]protocol %d >= NPROTO(%d)\n", ops->family,
                       NPROTO);
                return -ENOBUFS;
        }
@@ -2574,8 +2656,9 @@ int sock_register(const struct net_proto_family *ops)
                err = 0;
        }
        spin_unlock(&net_family_lock);
-
-       printk(KERN_INFO "NET: Registered protocol family %d\n", ops->family);
+    #ifdef CONFIG_MTK_NET_LOGGING 
+       printk(KERN_INFO "[mtk_net][socekt]NET: Registered protocol family %d\n", ops->family);
+       #endif
        return err;
 }
 EXPORT_SYMBOL(sock_register);
@@ -2602,8 +2685,9 @@ void sock_unregister(int family)
        spin_unlock(&net_family_lock);
 
        synchronize_rcu();
-
-       printk(KERN_INFO "NET: Unregistered protocol family %d\n", family);
+    #ifdef CONFIG_MTK_NET_LOGGING 
+       printk(KERN_INFO "[mtk_net][socket]NET: Unregistered protocol family %d\n", family);
+       #endif
 }
 EXPORT_SYMBOL(sock_unregister);