--- /dev/null
+From 56668f74d058b5c84a72bbb25300a343694c0b40 Mon Sep 17 00:00:00 2001
+From: Bing-Jhong Billy Jheng <billy@starlabs.sg>
+Date: Thu, 2 Mar 2023 21:00:06 +0800
+Subject: io_uring: add missing lock in io_get_file_fixed
+
+From: Bing-Jhong Billy Jheng <billy@starlabs.sg>
+
+io_get_file_fixed will access io_uring's context. Lock it if it is
+invoked unlocked (eg via io-wq) to avoid a race condition with fixed
+files getting unregistered.
+
+No single upstream patch exists for this issue, it was fixed as part
+of the file assignment changes that went into the 5.18 cycle.
+
+Signed-off-by: Jheng, Bing-Jhong Billy <billy@starlabs.sg>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io_uring.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1092,7 +1092,8 @@ static int __io_register_rsrc_update(str
+ unsigned nr_args);
+ static void io_clean_op(struct io_kiocb *req);
+ static struct file *io_file_get(struct io_ring_ctx *ctx,
+- struct io_kiocb *req, int fd, bool fixed);
++ struct io_kiocb *req, int fd, bool fixed,
++ unsigned int issue_flags);
+ static void __io_queue_sqe(struct io_kiocb *req);
+ static void io_rsrc_put_work(struct work_struct *work);
+
+@@ -3975,7 +3976,7 @@ static int io_tee(struct io_kiocb *req,
+ return -EAGAIN;
+
+ in = io_file_get(req->ctx, req, sp->splice_fd_in,
+- (sp->flags & SPLICE_F_FD_IN_FIXED));
++ (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
+ if (!in) {
+ ret = -EBADF;
+ goto done;
+@@ -4015,7 +4016,7 @@ static int io_splice(struct io_kiocb *re
+ return -EAGAIN;
+
+ in = io_file_get(req->ctx, req, sp->splice_fd_in,
+- (sp->flags & SPLICE_F_FD_IN_FIXED));
++ (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
+ if (!in) {
+ ret = -EBADF;
+ goto done;
+@@ -6876,13 +6877,16 @@ static void io_fixed_file_set(struct io_
+ }
+
+ static inline struct file *io_file_get_fixed(struct io_ring_ctx *ctx,
+- struct io_kiocb *req, int fd)
++ struct io_kiocb *req, int fd,
++ unsigned int issue_flags)
+ {
+- struct file *file;
++ struct file *file = NULL;
+ unsigned long file_ptr;
+
++ io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
++
+ if (unlikely((unsigned int)fd >= ctx->nr_user_files))
+- return NULL;
++ goto out;
+ fd = array_index_nospec(fd, ctx->nr_user_files);
+ file_ptr = io_fixed_file_slot(&ctx->file_table, fd)->file_ptr;
+ file = (struct file *) (file_ptr & FFS_MASK);
+@@ -6890,6 +6894,8 @@ static inline struct file *io_file_get_f
+ /* mask in overlapping REQ_F and FFS bits */
+ req->flags |= (file_ptr << REQ_F_NOWAIT_READ_BIT);
+ io_req_set_rsrc_node(req);
++out:
++ io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
+ return file;
+ }
+
+@@ -6907,10 +6913,11 @@ static struct file *io_file_get_normal(s
+ }
+
+ static inline struct file *io_file_get(struct io_ring_ctx *ctx,
+- struct io_kiocb *req, int fd, bool fixed)
++ struct io_kiocb *req, int fd, bool fixed,
++ unsigned int issue_flags)
+ {
+ if (fixed)
+- return io_file_get_fixed(ctx, req, fd);
++ return io_file_get_fixed(ctx, req, fd, issue_flags);
+ else
+ return io_file_get_normal(ctx, req, fd);
+ }
+@@ -7132,7 +7139,7 @@ static int io_init_req(struct io_ring_ct
+
+ if (io_op_defs[req->opcode].needs_file) {
+ req->file = io_file_get(ctx, req, READ_ONCE(sqe->fd),
+- (sqe_flags & IOSQE_FIXED_FILE));
++ (sqe_flags & IOSQE_FIXED_FILE), 0);
+ if (unlikely(!req->file))
+ ret = -EBADF;
+ }