net: switch sendto() and recvfrom() to import_single_range()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 21 Mar 2015 23:12:32 +0000 (19:12 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Apr 2015 04:02:21 +0000 (00:02 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
net/socket.c

index 989b1ae32afaad0cd2519b83a2c843ac4074528e..46f0e1d752b327ae9d1e8bd0e06f8f6ed5ea59a3 100644 (file)
@@ -1650,18 +1650,14 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        struct iovec iov;
        int fput_needed;
 
-       if (len > INT_MAX)
-               len = INT_MAX;
-       if (unlikely(!access_ok(VERIFY_READ, buff, len)))
-               return -EFAULT;
+       err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
+       if (unlikely(err))
+               return err;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       iov.iov_base = buff;
-       iov.iov_len = len;
        msg.msg_name = NULL;
-       iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len);
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_namelen = 0;
@@ -1675,7 +1671,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        msg.msg_flags = flags;
-       err = sock_sendmsg(sock, &msg, len);
+       err = sock_sendmsg(sock, &msg, iov_iter_count(&msg.msg_iter));
 
 out_put:
        fput_light(sock->file, fput_needed);
@@ -1710,26 +1706,22 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        int err, err2;
        int fput_needed;
 
-       if (size > INT_MAX)
-               size = INT_MAX;
-       if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size)))
-               return -EFAULT;
+       err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
+       if (unlikely(err))
+               return err;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
-       iov.iov_len = size;
-       iov.iov_base = ubuf;
-       iov_iter_init(&msg.msg_iter, READ, &iov, 1, size);
        /* 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);
+       err = sock_recvmsg(sock, &msg, iov_iter_count(&msg.msg_iter), flags);
 
        if (err >= 0 && addr != NULL) {
                err2 = move_addr_to_user(&address,