From: Pavel Begunkov asml.silence@gmail.com
stable inclusion from stable-v5.10.204 commit 3fe1ea5f921bf5b71cbfdc4469fb96c05936610e category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8RWPE CVE: CVE-2023-6531
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
---------------------------
commit 705318a99a138c29a512a72c3e0043b3cd7f55f4 upstream.
File reference cycles have caused lots of problems for io_uring in the past, and it still doesn't work exactly right and races with unix_stream_read_generic(). The safest fix would be to completely disallow sending io_uring files via sockets via SCM_RIGHT, so there are no possible cycles invloving registered files and thus rendering SCM accounting on the io_uring side unnecessary.
Cc: stable@vger.kernel.org Fixes: 0091bfc81741b ("io_uring/af_unix: defer registered files gc to io_uring release") Reported-and-suggested-by: Jann Horn jannh@google.com Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/c716c88321939156909cfa1bd8b0faaf1c804103.170186879... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
[cherry-pick the cve bugfix from 5.10-stable] Signed-off-by: Liu Jian liujian56@huawei.com
Conflicts: io_uring/io_uring.c net/core/scm.c --- fs/io_uring.c | 49 ------------------------------------------------- net/core/scm.c | 6 ++++++ 2 files changed, 6 insertions(+), 49 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c index 88eca93c55b7..018d38bec473 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7220,49 +7220,6 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, return ret; }
-static int io_sqe_file_register(struct io_ring_ctx *ctx, struct file *file, - int index) -{ -#if defined(CONFIG_UNIX) - struct sock *sock = ctx->ring_sock->sk; - struct sk_buff_head *head = &sock->sk_receive_queue; - struct sk_buff *skb; - - /* - * See if we can merge this file into an existing skb SCM_RIGHTS - * file set. If there's no room, fall back to allocating a new skb - * and filling it in. - */ - spin_lock_irq(&head->lock); - skb = skb_peek(head); - if (skb) { - struct scm_fp_list *fpl = UNIXCB(skb).fp; - - if (fpl->count < SCM_MAX_FD) { - __skb_unlink(skb, head); - spin_unlock_irq(&head->lock); - fpl->fp[fpl->count] = get_file(file); - unix_inflight(fpl->user, fpl->fp[fpl->count]); - fpl->count++; - spin_lock_irq(&head->lock); - __skb_queue_head(head, skb); - } else { - skb = NULL; - } - } - spin_unlock_irq(&head->lock); - - if (skb) { - fput(file); - return 0; - } - - return __io_sqe_files_scm(ctx, 1, index); -#else - return 0; -#endif -} - static int io_queue_file_removal(struct fixed_file_data *data, struct file *file) { @@ -7342,12 +7299,6 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, break; } table->files[index] = file; - err = io_sqe_file_register(ctx, file, i); - if (err) { - table->files[index] = NULL; - fput(file); - break; - } } nr_args--; done++; diff --git a/net/core/scm.c b/net/core/scm.c index b1ff8a441748..4cf9ef6e0250 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -29,6 +29,7 @@ #include <linux/pid.h> #include <linux/nsproxy.h> #include <linux/slab.h> +#include <linux/fs.h>
#include <linux/uaccess.h>
@@ -106,6 +107,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
if (fd < 0 || !(file = fget_raw(fd))) return -EBADF; + /* don't allow io_uring files */ + if (io_uring_get_socket(file)) { + fput(file); + return -EINVAL; + } *fpp++ = file; fpl->count++; }