]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: copy from user before calling __get_compat_msghdr
authorDylan Yudaken <dylany@fb.com>
Thu, 14 Jul 2022 11:02:57 +0000 (04:02 -0700)
committerJens Axboe <axboe@kernel.dk>
Mon, 25 Jul 2022 00:39:17 +0000 (18:39 -0600)
this is in preparation for multishot receive from io_uring, where it needs
to have access to the original struct user_msghdr.

functionally this should be a no-op.

Acked-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Dylan Yudaken <dylany@fb.com>
Link: https://lore.kernel.org/r/20220714110258.1336200-3-dylany@fb.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/net/compat.h
io_uring/net.c
net/compat.c

index 595fee069b825017002c4b640a50ba5f7a302a05..84c163f40f38a53e4369debb60fada2988237633 100644 (file)
@@ -46,9 +46,8 @@ struct compat_rtentry {
        unsigned short  rt_irtt;        /* Initial RTT                  */
 };
 
-int __get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg,
-                       struct sockaddr __user **save_addr, compat_uptr_t *ptr,
-                       compat_size_t *len);
+int __get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr *msg,
+                       struct sockaddr __user **save_addr);
 int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *,
                      struct sockaddr __user **, struct iovec **);
 int put_cmsg_compat(struct msghdr*, int, int, int, void *);
index da7667ed36106d96cd8cc0267734919cd98683c8..5bc3440a829012e46b936b50e1e48e9fc034a6fb 100644 (file)
@@ -369,24 +369,25 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
                                        struct io_async_msghdr *iomsg)
 {
        struct io_sr_msg *sr = io_kiocb_to_cmd(req);
+       struct compat_msghdr msg;
        struct compat_iovec __user *uiov;
-       compat_uptr_t ptr;
-       compat_size_t len;
        int ret;
 
-       ret = __get_compat_msghdr(&iomsg->msg, sr->umsg_compat, &iomsg->uaddr,
-                                 &ptr, &len);
+       if (copy_from_user(&msg, sr->umsg_compat, sizeof(msg)))
+               return -EFAULT;
+
+       ret = __get_compat_msghdr(&iomsg->msg, sr->umsg_compat, &iomsg->uaddr);
        if (ret)
                return ret;
 
-       uiov = compat_ptr(ptr);
+       uiov = compat_ptr(msg.msg_iov);
        if (req->flags & REQ_F_BUFFER_SELECT) {
                compat_ssize_t clen;
 
-               if (len == 0) {
+               if (msg.msg_iovlen == 0) {
                        sr->len = 0;
                        iomsg->free_iov = NULL;
-               } else if (len > 1) {
+               } else if (msg.msg_iovlen > 1) {
                        return -EINVAL;
                } else {
                        if (!access_ok(uiov, sizeof(*uiov)))
@@ -400,7 +401,7 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
                }
        } else {
                iomsg->free_iov = iomsg->fast_iov;
-               ret = __import_iovec(READ, (struct iovec __user *)uiov, len,
+               ret = __import_iovec(READ, (struct iovec __user *)uiov, msg.msg_iovlen,
                                   UIO_FASTIOV, &iomsg->free_iov,
                                   &iomsg->msg.msg_iter, true);
                if (ret < 0)
index 210fc3b4d0d833a1360c76fb455effda93864320..513aa9a3fc646626fc3b27a288ccc4ada0cc127d 100644 (file)
 #include <net/compat.h>
 
 int __get_compat_msghdr(struct msghdr *kmsg,
-                       struct compat_msghdr __user *umsg,
-                       struct sockaddr __user **save_addr,
-                       compat_uptr_t *ptr, compat_size_t *len)
+                       struct compat_msghdr *msg,
+                       struct sockaddr __user **save_addr)
 {
-       struct compat_msghdr msg;
        ssize_t err;
 
-       if (copy_from_user(&msg, umsg, sizeof(*umsg)))
-               return -EFAULT;
-
-       kmsg->msg_flags = msg.msg_flags;
-       kmsg->msg_namelen = msg.msg_namelen;
+       kmsg->msg_flags = msg->msg_flags;
+       kmsg->msg_namelen = msg->msg_namelen;
 
-       if (!msg.msg_name)
+       if (!msg->msg_name)
                kmsg->msg_namelen = 0;
 
        if (kmsg->msg_namelen < 0)
@@ -57,15 +52,15 @@ int __get_compat_msghdr(struct msghdr *kmsg,
                kmsg->msg_namelen = sizeof(struct sockaddr_storage);
 
        kmsg->msg_control_is_user = true;
-       kmsg->msg_control_user = compat_ptr(msg.msg_control);
-       kmsg->msg_controllen = msg.msg_controllen;
+       kmsg->msg_control_user = compat_ptr(msg->msg_control);
+       kmsg->msg_controllen = msg->msg_controllen;
 
        if (save_addr)
-               *save_addr = compat_ptr(msg.msg_name);
+               *save_addr = compat_ptr(msg->msg_name);
 
-       if (msg.msg_name && kmsg->msg_namelen) {
+       if (msg->msg_name && kmsg->msg_namelen) {
                if (!save_addr) {
-                       err = move_addr_to_kernel(compat_ptr(msg.msg_name),
+                       err = move_addr_to_kernel(compat_ptr(msg->msg_name),
                                                  kmsg->msg_namelen,
                                                  kmsg->msg_name);
                        if (err < 0)
@@ -76,12 +71,10 @@ int __get_compat_msghdr(struct msghdr *kmsg,
                kmsg->msg_namelen = 0;
        }
 
-       if (msg.msg_iovlen > UIO_MAXIOV)
+       if (msg->msg_iovlen > UIO_MAXIOV)
                return -EMSGSIZE;
 
        kmsg->msg_iocb = NULL;
-       *ptr = msg.msg_iov;
-       *len = msg.msg_iovlen;
        return 0;
 }
 
@@ -90,15 +83,17 @@ int get_compat_msghdr(struct msghdr *kmsg,
                      struct sockaddr __user **save_addr,
                      struct iovec **iov)
 {
-       compat_uptr_t ptr;
-       compat_size_t len;
+       struct compat_msghdr msg;
        ssize_t err;
 
-       err = __get_compat_msghdr(kmsg, umsg, save_addr, &ptr, &len);
+       if (copy_from_user(&msg, umsg, sizeof(*umsg)))
+               return -EFAULT;
+
+       err = __get_compat_msghdr(kmsg, umsg, save_addr);
        if (err)
                return err;
 
-       err = import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr), len,
+       err = import_iovec(save_addr ? READ : WRITE, compat_ptr(msg.msg_iov), msg.msg_iovlen,
                           UIO_FASTIOV, iov, &kmsg->msg_iter);
        return err < 0 ? err : 0;
 }