|
@@ -689,8 +689,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
|
|
|
* the following is safe, since for compiler definitions of kvec and
|
|
|
* iovec are identical, yielding the same in-core layout and alignment
|
|
|
*/
|
|
|
- msg->msg_iov = (struct iovec *)vec;
|
|
|
- msg->msg_iovlen = num;
|
|
|
+ iov_iter_init(&msg->msg_iter, WRITE, (struct iovec *)vec, num, size);
|
|
|
result = sock_sendmsg(sock, msg, size);
|
|
|
set_fs(oldfs);
|
|
|
return result;
|
|
@@ -853,7 +852,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
|
|
|
* the following is safe, since for compiler definitions of kvec and
|
|
|
* iovec are identical, yielding the same in-core layout and alignment
|
|
|
*/
|
|
|
- msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
|
|
|
+ iov_iter_init(&msg->msg_iter, READ, (struct iovec *)vec, num, size);
|
|
|
result = sock_recvmsg(sock, msg, size, flags);
|
|
|
set_fs(oldfs);
|
|
|
return result;
|
|
@@ -913,8 +912,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
|
|
|
msg->msg_namelen = 0;
|
|
|
msg->msg_control = NULL;
|
|
|
msg->msg_controllen = 0;
|
|
|
- msg->msg_iov = (struct iovec *)iov;
|
|
|
- msg->msg_iovlen = nr_segs;
|
|
|
+ iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size);
|
|
|
msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
|
|
|
|
|
|
return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
|
|
@@ -953,8 +951,7 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
|
|
|
msg->msg_namelen = 0;
|
|
|
msg->msg_control = NULL;
|
|
|
msg->msg_controllen = 0;
|
|
|
- msg->msg_iov = (struct iovec *)iov;
|
|
|
- msg->msg_iovlen = nr_segs;
|
|
|
+ iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size);
|
|
|
msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
|
|
|
if (sock->type == SOCK_SEQPACKET)
|
|
|
msg->msg_flags |= MSG_EOR;
|
|
@@ -1798,8 +1795,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
|
|
|
iov.iov_base = buff;
|
|
|
iov.iov_len = len;
|
|
|
msg.msg_name = NULL;
|
|
|
- msg.msg_iov = &iov;
|
|
|
- msg.msg_iovlen = 1;
|
|
|
+ iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len);
|
|
|
msg.msg_control = NULL;
|
|
|
msg.msg_controllen = 0;
|
|
|
msg.msg_namelen = 0;
|
|
@@ -1856,10 +1852,9 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
|
|
|
|
|
|
msg.msg_control = NULL;
|
|
|
msg.msg_controllen = 0;
|
|
|
- msg.msg_iovlen = 1;
|
|
|
- msg.msg_iov = &iov;
|
|
|
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 */
|
|
@@ -1993,13 +1988,14 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
|
|
|
{
|
|
|
struct sockaddr __user *uaddr;
|
|
|
struct iovec __user *uiov;
|
|
|
+ size_t nr_segs;
|
|
|
ssize_t err;
|
|
|
|
|
|
if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
|
|
|
__get_user(uaddr, &umsg->msg_name) ||
|
|
|
__get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
|
|
|
__get_user(uiov, &umsg->msg_iov) ||
|
|
|
- __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
|
|
|
+ __get_user(nr_segs, &umsg->msg_iovlen) ||
|
|
|
__get_user(kmsg->msg_control, &umsg->msg_control) ||
|
|
|
__get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
|
|
|
__get_user(kmsg->msg_flags, &umsg->msg_flags))
|
|
@@ -2029,14 +2025,15 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
|
|
|
kmsg->msg_namelen = 0;
|
|
|
}
|
|
|
|
|
|
- if (kmsg->msg_iovlen > UIO_MAXIOV)
|
|
|
+ if (nr_segs > UIO_MAXIOV)
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
err = rw_copy_check_uvector(save_addr ? READ : WRITE,
|
|
|
- uiov, kmsg->msg_iovlen,
|
|
|
+ uiov, nr_segs,
|
|
|
UIO_FASTIOV, *iov, iov);
|
|
|
if (err >= 0)
|
|
|
- kmsg->msg_iov = *iov;
|
|
|
+ iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
|
|
|
+ *iov, nr_segs, err);
|
|
|
return err;
|
|
|
}
|
|
|
|