]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/socket.c
Merge branch 'iocb' into for-davem
[karo-tx-linux.git] / net / socket.c
index 95d3085cb477af5eff99c48b1d3a5f1be76e0274..989b1ae32afaad0cd2519b83a2c843ac4074528e 100644 (file)
@@ -798,7 +798,8 @@ static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        struct file *file = iocb->ki_filp;
        struct socket *sock = file->private_data;
-       struct msghdr msg = {.msg_iter = *to};
+       struct msghdr msg = {.msg_iter = *to,
+                            .msg_iocb = iocb};
        ssize_t res;
 
        if (file->f_flags & O_NONBLOCK)
@@ -807,10 +808,10 @@ static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
        if (iocb->ki_pos != 0)
                return -ESPIPE;
 
-       if (iocb->ki_nbytes == 0)       /* Match SYS5 behaviour */
+       if (!iov_iter_count(to))        /* Match SYS5 behaviour */
                return 0;
 
-       res = sock_recvmsg(sock, &msg, iocb->ki_nbytes, msg.msg_flags);
+       res = sock_recvmsg(sock, &msg, iov_iter_count(to), msg.msg_flags);
        *to = msg.msg_iter;
        return res;
 }
@@ -819,7 +820,8 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
        struct socket *sock = file->private_data;
-       struct msghdr msg = {.msg_iter = *from};
+       struct msghdr msg = {.msg_iter = *from,
+                            .msg_iocb = iocb};
        ssize_t res;
 
        if (iocb->ki_pos != 0)
@@ -831,7 +833,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (sock->type == SOCK_SEQPACKET)
                msg.msg_flags |= MSG_EOR;
 
-       res = sock_sendmsg(sock, &msg, iocb->ki_nbytes);
+       res = sock_sendmsg(sock, &msg, iov_iter_count(from));
        *from = msg.msg_iter;
        return res;
 }
@@ -1650,6 +1652,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;
@@ -1708,6 +1712,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;
@@ -1890,6 +1896,8 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
        if (nr_segs > UIO_MAXIOV)
                return -EMSGSIZE;
 
+       kmsg->msg_iocb = NULL;
+
        err = rw_copy_check_uvector(save_addr ? READ : WRITE,
                                    uiov, nr_segs,
                                    UIO_FASTIOV, *iov, iov);