]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: disallow ancillary data for __sys_{send,recv}msg_file()
authorJens Axboe <axboe@kernel.dk>
Tue, 26 Nov 2019 00:04:13 +0000 (17:04 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 26 Nov 2019 22:02:53 +0000 (15:02 -0700)
Only io_uring uses (and added) these, and we want to disallow the
use of sendmsg/recvmsg for anything but regular data transfers.
Use the newly added prep helper to split the msghdr copy out from
the core function, to check for msg_control and msg_controllen
settings. If either is set, we return -EINVAL.

Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
net/socket.c

index 98568ae58bad4309c9df9e187eaedcdc2cf32906..c78c3d37c884fff5325e5e342d1ad8902fe5854b 100644 (file)
@@ -2389,12 +2389,27 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
 /*
  *     BSD sendmsg interface
  */
-long __sys_sendmsg_sock(struct socket *sock, struct user_msghdr __user *msg,
+long __sys_sendmsg_sock(struct socket *sock, struct user_msghdr __user *umsg,
                        unsigned int flags)
 {
-       struct msghdr msg_sys;
+       struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+       struct sockaddr_storage address;
+       struct msghdr msg = { .msg_name = &address };
+       ssize_t err;
+
+       err = sendmsg_copy_msghdr(&msg, umsg, flags, &iov);
+       if (err)
+               return err;
+       /* disallow ancillary data requests from this path */
+       if (msg.msg_control || msg.msg_controllen) {
+               err = -EINVAL;
+               goto out;
+       }
 
-       return ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
+       err = ____sys_sendmsg(sock, &msg, flags, NULL, 0);
+out:
+       kfree(iov);
+       return err;
 }
 
 long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
@@ -2593,12 +2608,28 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
  *     BSD recvmsg interface
  */
 
-long __sys_recvmsg_sock(struct socket *sock, struct user_msghdr __user *msg,
+long __sys_recvmsg_sock(struct socket *sock, struct user_msghdr __user *umsg,
                        unsigned int flags)
 {
-       struct msghdr msg_sys;
+       struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+       struct sockaddr_storage address;
+       struct msghdr msg = { .msg_name = &address };
+       struct sockaddr __user *uaddr;
+       ssize_t err;
 
-       return ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
+       err = recvmsg_copy_msghdr(&msg, umsg, flags, &uaddr, &iov);
+       if (err)
+               return err;
+       /* disallow ancillary data requests from this path */
+       if (msg.msg_control || msg.msg_controllen) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = ____sys_recvmsg(sock, &msg, umsg, uaddr, flags, 0);
+out:
+       kfree(iov);
+       return err;
 }
 
 long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,