]> Pileus Git - ~andy/linux/blobdiff - net/socket.c
ipv4: gso: make inet_gso_segment() stackable
[~andy/linux] / net / socket.c
index b2d7c629eeb9f2de785600ed189080af9be02a3e..c226aceee65b8b8c59d93d6a133a04c86177ceef 100644 (file)
@@ -854,11 +854,6 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
 }
 EXPORT_SYMBOL(kernel_recvmsg);
 
-static void sock_aio_dtor(struct kiocb *iocb)
-{
-       kfree(iocb->private);
-}
-
 static ssize_t sock_sendpage(struct file *file, struct page *page,
                             int offset, size_t size, loff_t *ppos, int more)
 {
@@ -889,12 +884,8 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
 static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
                                         struct sock_iocb *siocb)
 {
-       if (!is_sync_kiocb(iocb)) {
-               siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
-               if (!siocb)
-                       return NULL;
-               iocb->ki_dtor = sock_aio_dtor;
-       }
+       if (!is_sync_kiocb(iocb))
+               BUG();
 
        siocb->kiocb = iocb;
        iocb->private = siocb;
@@ -931,7 +922,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
        if (pos != 0)
                return -ESPIPE;
 
-       if (iocb->ki_left == 0) /* Match SYS5 behaviour */
+       if (iocb->ki_nbytes == 0)       /* Match SYS5 behaviour */
                return 0;
 
 
@@ -1973,6 +1964,16 @@ struct used_address {
        unsigned int name_len;
 };
 
+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 > sizeof(struct sockaddr_storage))
+               return -EINVAL;
+       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)
@@ -1991,8 +1992,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;
@@ -2200,8 +2204,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;
@@ -3072,12 +3079,12 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
 
        uifmap32 = &uifr32->ifr_ifru.ifru_map;
        err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
-       err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
-       err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
-       err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
-       err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
-       err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
-       err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
+       err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
+       err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
+       err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
+       err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
+       err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
+       err |= get_user(ifr.ifr_map.port, &uifmap32->port);
        if (err)
                return -EFAULT;
 
@@ -3088,12 +3095,12 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
 
        if (cmd == SIOCGIFMAP && !err) {
                err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
-               err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
-               err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
-               err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
-               err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
-               err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
-               err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
+               err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
+               err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
+               err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
+               err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
+               err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
+               err |= put_user(ifr.ifr_map.port, &uifmap32->port);
                if (err)
                        err = -EFAULT;
        }
@@ -3167,25 +3174,25 @@ static int routing_ioctl(struct net *net, struct socket *sock,
                struct in6_rtmsg32 __user *ur6 = argp;
                ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
                        3 * sizeof(struct in6_addr));
-               ret |= __get_user(r6.rtmsg_type, &(ur6->rtmsg_type));
-               ret |= __get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
-               ret |= __get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
-               ret |= __get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric));
-               ret |= __get_user(r6.rtmsg_info, &(ur6->rtmsg_info));
-               ret |= __get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags));
-               ret |= __get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
+               ret |= get_user(r6.rtmsg_type, &(ur6->rtmsg_type));
+               ret |= get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
+               ret |= get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
+               ret |= get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric));
+               ret |= get_user(r6.rtmsg_info, &(ur6->rtmsg_info));
+               ret |= get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags));
+               ret |= get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
 
                r = (void *) &r6;
        } else { /* ipv4 */
                struct rtentry32 __user *ur4 = argp;
                ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
                                        3 * sizeof(struct sockaddr));
-               ret |= __get_user(r4.rt_flags, &(ur4->rt_flags));
-               ret |= __get_user(r4.rt_metric, &(ur4->rt_metric));
-               ret |= __get_user(r4.rt_mtu, &(ur4->rt_mtu));
-               ret |= __get_user(r4.rt_window, &(ur4->rt_window));
-               ret |= __get_user(r4.rt_irtt, &(ur4->rt_irtt));
-               ret |= __get_user(rtdev, &(ur4->rt_dev));
+               ret |= get_user(r4.rt_flags, &(ur4->rt_flags));
+               ret |= get_user(r4.rt_metric, &(ur4->rt_metric));
+               ret |= get_user(r4.rt_mtu, &(ur4->rt_mtu));
+               ret |= get_user(r4.rt_window, &(ur4->rt_window));
+               ret |= get_user(r4.rt_irtt, &(ur4->rt_irtt));
+               ret |= get_user(rtdev, &(ur4->rt_dev));
                if (rtdev) {
                        ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
                        r4.rt_dev = (char __user __force *)devname;