--- /dev/null
+From e106d9fcc66411426c16ea3c3579e49cf2819b3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2019 08:52:30 -0700
+Subject: io_uring: async workers should inherit the user creds
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 181e448d8709e517c9c7b523fcd209f24eb38ca7 ]
+
+If we don't inherit the original task creds, then we can confuse users
+like fuse that pass creds in the request header. See link below on
+identical aio issue.
+
+Link: https://lore.kernel.org/linux-fsdevel/26f0d78e-99ca-2f1b-78b9-433088053a61@scylladb.com/T/#u
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/io_uring.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/fs/io_uring.c b/fs/io_uring.c
+index 56c23dee98117..f563a581b924c 100644
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -260,6 +260,8 @@ struct io_ring_ctx {
+
+ struct user_struct *user;
+
++ struct cred *creds;
++
+ struct completion ctx_done;
+
+ struct {
+@@ -1633,8 +1635,11 @@ static void io_poll_complete_work(struct work_struct *work)
+ struct io_poll_iocb *poll = &req->poll;
+ struct poll_table_struct pt = { ._key = poll->events };
+ struct io_ring_ctx *ctx = req->ctx;
++ const struct cred *old_cred;
+ __poll_t mask = 0;
+
++ old_cred = override_creds(ctx->creds);
++
+ if (!READ_ONCE(poll->canceled))
+ mask = vfs_poll(poll->file, &pt) & poll->events;
+
+@@ -1649,7 +1654,7 @@ static void io_poll_complete_work(struct work_struct *work)
+ if (!mask && !READ_ONCE(poll->canceled)) {
+ add_wait_queue(poll->head, &poll->wait);
+ spin_unlock_irq(&ctx->completion_lock);
+- return;
++ goto out;
+ }
+ list_del_init(&req->list);
+ io_poll_complete(ctx, req, mask);
+@@ -1657,6 +1662,8 @@ static void io_poll_complete_work(struct work_struct *work)
+
+ io_cqring_ev_posted(ctx);
+ io_put_req(req);
++out:
++ revert_creds(old_cred);
+ }
+
+ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
+@@ -1906,10 +1913,12 @@ static void io_sq_wq_submit_work(struct work_struct *work)
+ struct io_ring_ctx *ctx = req->ctx;
+ struct mm_struct *cur_mm = NULL;
+ struct async_list *async_list;
++ const struct cred *old_cred;
+ LIST_HEAD(req_list);
+ mm_segment_t old_fs;
+ int ret;
+
++ old_cred = override_creds(ctx->creds);
+ async_list = io_async_list_from_sqe(ctx, req->submit.sqe);
+ restart:
+ do {
+@@ -2017,6 +2026,7 @@ static void io_sq_wq_submit_work(struct work_struct *work)
+ unuse_mm(cur_mm);
+ mmput(cur_mm);
+ }
++ revert_creds(old_cred);
+ }
+
+ /*
+@@ -2354,6 +2364,7 @@ static int io_sq_thread(void *data)
+ {
+ struct io_ring_ctx *ctx = data;
+ struct mm_struct *cur_mm = NULL;
++ const struct cred *old_cred;
+ mm_segment_t old_fs;
+ DEFINE_WAIT(wait);
+ unsigned inflight;
+@@ -2363,6 +2374,7 @@ static int io_sq_thread(void *data)
+
+ old_fs = get_fs();
+ set_fs(USER_DS);
++ old_cred = override_creds(ctx->creds);
+
+ timeout = inflight = 0;
+ while (!kthread_should_park()) {
+@@ -2473,6 +2485,7 @@ static int io_sq_thread(void *data)
+ unuse_mm(cur_mm);
+ mmput(cur_mm);
+ }
++ revert_creds(old_cred);
+
+ kthread_parkme();
+
+@@ -3142,6 +3155,8 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ io_unaccount_mem(ctx->user,
+ ring_pages(ctx->sq_entries, ctx->cq_entries));
+ free_uid(ctx->user);
++ if (ctx->creds)
++ put_cred(ctx->creds);
+ kfree(ctx);
+ }
+
+@@ -3419,6 +3434,12 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
+ ctx->account_mem = account_mem;
+ ctx->user = user;
+
++ ctx->creds = prepare_creds();
++ if (!ctx->creds) {
++ ret = -ENOMEM;
++ goto err;
++ }
++
+ ret = io_allocate_scq_urings(ctx, p);
+ if (ret)
+ goto err;
+--
+2.20.1
+
--- /dev/null
+From cfda91f3a3100b6668a4baacd087572e90d081c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2019 17:04:13 -0700
+Subject: net: disallow ancillary data for __sys_{send,recv}msg_file()
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit d69e07793f891524c6bbf1e75b9ae69db4450953 ]
+
+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>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/socket.c | 43 +++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 37 insertions(+), 6 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index fbe08d7df7732..d7a106028f0e0 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2357,12 +2357,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,
+@@ -2561,12 +2576,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,
+--
+2.20.1
+
--- /dev/null
+From 17ae4d73b94236ef718b81a247b362b508d7d0f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2019 14:27:34 -0700
+Subject: net: separate out the msghdr copy from ___sys_{send,recv}msg()
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 4257c8ca13b084550574b8c9a667d9c90ff746eb ]
+
+This is in preparation for enabling the io_uring helpers for sendmsg
+and recvmsg to first copy the header for validation before continuing
+with the operation.
+
+There should be no functional changes in this patch.
+
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/socket.c | 141 ++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 95 insertions(+), 46 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index 6a9ab7a8b1d2c..fbe08d7df7732 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2232,15 +2232,10 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
+ return err < 0 ? err : 0;
+ }
+
+-static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+- struct msghdr *msg_sys, unsigned int flags,
+- struct used_address *used_address,
+- unsigned int allowed_msghdr_flags)
++static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
++ unsigned int flags, struct used_address *used_address,
++ unsigned int allowed_msghdr_flags)
+ {
+- struct compat_msghdr __user *msg_compat =
+- (struct compat_msghdr __user *)msg;
+- struct sockaddr_storage address;
+- struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+ unsigned char ctl[sizeof(struct cmsghdr) + 20]
+ __aligned(sizeof(__kernel_size_t));
+ /* 20 is size of ipv6_pktinfo */
+@@ -2248,19 +2243,10 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+ int ctl_len;
+ ssize_t err;
+
+- msg_sys->msg_name = &address;
+-
+- if (MSG_CMSG_COMPAT & flags)
+- err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
+- else
+- err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
+- if (err < 0)
+- return err;
+-
+ err = -ENOBUFS;
+
+ if (msg_sys->msg_controllen > INT_MAX)
+- goto out_freeiov;
++ goto out;
+ flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
+ ctl_len = msg_sys->msg_controllen;
+ if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
+@@ -2268,7 +2254,7 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+ cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
+ sizeof(ctl));
+ if (err)
+- goto out_freeiov;
++ goto out;
+ ctl_buf = msg_sys->msg_control;
+ ctl_len = msg_sys->msg_controllen;
+ } else if (ctl_len) {
+@@ -2277,7 +2263,7 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+ if (ctl_len > sizeof(ctl)) {
+ ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
+ if (ctl_buf == NULL)
+- goto out_freeiov;
++ goto out;
+ }
+ err = -EFAULT;
+ /*
+@@ -2323,7 +2309,47 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+ out_freectl:
+ if (ctl_buf != ctl)
+ sock_kfree_s(sock->sk, ctl_buf, ctl_len);
+-out_freeiov:
++out:
++ return err;
++}
++
++static int sendmsg_copy_msghdr(struct msghdr *msg,
++ struct user_msghdr __user *umsg, unsigned flags,
++ struct iovec **iov)
++{
++ int err;
++
++ if (flags & MSG_CMSG_COMPAT) {
++ struct compat_msghdr __user *msg_compat;
++
++ msg_compat = (struct compat_msghdr __user *) umsg;
++ err = get_compat_msghdr(msg, msg_compat, NULL, iov);
++ } else {
++ err = copy_msghdr_from_user(msg, umsg, NULL, iov);
++ }
++ if (err < 0)
++ return err;
++
++ return 0;
++}
++
++static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
++ struct msghdr *msg_sys, unsigned int flags,
++ struct used_address *used_address,
++ unsigned int allowed_msghdr_flags)
++{
++ struct sockaddr_storage address;
++ struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
++ ssize_t err;
++
++ msg_sys->msg_name = &address;
++
++ err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov);
++ if (err < 0)
++ return err;
++
++ err = ____sys_sendmsg(sock, msg_sys, flags, used_address,
++ allowed_msghdr_flags);
+ kfree(iov);
+ return err;
+ }
+@@ -2442,33 +2468,41 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
+ return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
+ }
+
+-static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
+- struct msghdr *msg_sys, unsigned int flags, int nosec)
++static int recvmsg_copy_msghdr(struct msghdr *msg,
++ struct user_msghdr __user *umsg, unsigned flags,
++ struct sockaddr __user **uaddr,
++ struct iovec **iov)
+ {
+- struct compat_msghdr __user *msg_compat =
+- (struct compat_msghdr __user *)msg;
+- struct iovec iovstack[UIO_FASTIOV];
+- struct iovec *iov = iovstack;
+- unsigned long cmsg_ptr;
+- int len;
+ ssize_t err;
+
+- /* kernel mode address */
+- struct sockaddr_storage addr;
+-
+- /* user mode address pointers */
+- struct sockaddr __user *uaddr;
+- int __user *uaddr_len = COMPAT_NAMELEN(msg);
+-
+- msg_sys->msg_name = &addr;
++ if (MSG_CMSG_COMPAT & flags) {
++ struct compat_msghdr __user *msg_compat;
+
+- if (MSG_CMSG_COMPAT & flags)
+- err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov);
+- else
+- err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov);
++ msg_compat = (struct compat_msghdr __user *) umsg;
++ err = get_compat_msghdr(msg, msg_compat, uaddr, iov);
++ } else {
++ err = copy_msghdr_from_user(msg, umsg, uaddr, iov);
++ }
+ if (err < 0)
+ return err;
+
++ return 0;
++}
++
++static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
++ struct user_msghdr __user *msg,
++ struct sockaddr __user *uaddr,
++ unsigned int flags, int nosec)
++{
++ struct compat_msghdr __user *msg_compat =
++ (struct compat_msghdr __user *) msg;
++ int __user *uaddr_len = COMPAT_NAMELEN(msg);
++ struct sockaddr_storage addr;
++ unsigned long cmsg_ptr;
++ int len;
++ ssize_t err;
++
++ msg_sys->msg_name = &addr;
+ cmsg_ptr = (unsigned long)msg_sys->msg_control;
+ msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
+
+@@ -2479,7 +2513,7 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
+ flags |= MSG_DONTWAIT;
+ err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
+ if (err < 0)
+- goto out_freeiov;
++ goto out;
+ len = err;
+
+ if (uaddr != NULL) {
+@@ -2487,12 +2521,12 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
+ msg_sys->msg_namelen, uaddr,
+ uaddr_len);
+ if (err < 0)
+- goto out_freeiov;
++ goto out;
+ }
+ err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
+ COMPAT_FLAGS(msg));
+ if (err)
+- goto out_freeiov;
++ goto out;
+ if (MSG_CMSG_COMPAT & flags)
+ err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
+ &msg_compat->msg_controllen);
+@@ -2500,10 +2534,25 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
+ err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
+ &msg->msg_controllen);
+ if (err)
+- goto out_freeiov;
++ goto out;
+ err = len;
++out:
++ return err;
++}
++
++static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
++ struct msghdr *msg_sys, unsigned int flags, int nosec)
++{
++ struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
++ /* user mode address pointers */
++ struct sockaddr __user *uaddr;
++ ssize_t err;
++
++ err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov);
++ if (err < 0)
++ return err;
+
+-out_freeiov:
++ err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
+ kfree(iov);
+ return err;
+ }
+--
+2.20.1
+