Skip to content

Commit af2a87d

Browse files
isilencejfvogel
authored andcommitted
io_uring: fix not locked access to fixed buf table
commit 05b538c upstream. We can look inside the fixed buffer table only while holding ->uring_lock, however in some cases we don't do the right async prep for IORING_OP_{WRITE,READ}_FIXED ending up with NULL req->imu forcing making an io-wq worker to try to resolve the fixed buffer without proper locking. Move req->imu setup into early req init paths, i.e. io_prep_rw(), which is called unconditionally for rw requests and under uring_lock. Fixes: 634d00d ("io_uring: add full-fledged dynamic buffers support") Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit ea512d540a55a75058ee4b78abfd1d499b229d1d) Signed-off-by: Jack Vogel <[email protected]>
1 parent 945182d commit af2a87d

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

fs/io_uring.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,15 +2932,24 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
29322932
kiocb->ki_complete = io_complete_rw;
29332933
}
29342934

2935+
/* used for fixed read/write too - just read unconditionally */
2936+
req->buf_index = READ_ONCE(sqe->buf_index);
2937+
req->imu = NULL;
2938+
29352939
if (req->opcode == IORING_OP_READ_FIXED ||
29362940
req->opcode == IORING_OP_WRITE_FIXED) {
2937-
req->imu = NULL;
2941+
struct io_ring_ctx *ctx = req->ctx;
2942+
u16 index;
2943+
2944+
if (unlikely(req->buf_index >= ctx->nr_user_bufs))
2945+
return -EFAULT;
2946+
index = array_index_nospec(req->buf_index, ctx->nr_user_bufs);
2947+
req->imu = ctx->user_bufs[index];
29382948
io_req_set_rsrc_node(req);
29392949
}
29402950

29412951
req->rw.addr = READ_ONCE(sqe->addr);
29422952
req->rw.len = READ_ONCE(sqe->len);
2943-
req->buf_index = READ_ONCE(sqe->buf_index);
29442953
return 0;
29452954
}
29462955

@@ -3066,18 +3075,9 @@ static int __io_import_fixed(struct io_kiocb *req, int rw, struct iov_iter *iter
30663075

30673076
static int io_import_fixed(struct io_kiocb *req, int rw, struct iov_iter *iter)
30683077
{
3069-
struct io_ring_ctx *ctx = req->ctx;
3070-
struct io_mapped_ubuf *imu = req->imu;
3071-
u16 index, buf_index = req->buf_index;
3072-
3073-
if (likely(!imu)) {
3074-
if (unlikely(buf_index >= ctx->nr_user_bufs))
3075-
return -EFAULT;
3076-
index = array_index_nospec(buf_index, ctx->nr_user_bufs);
3077-
imu = READ_ONCE(ctx->user_bufs[index]);
3078-
req->imu = imu;
3079-
}
3080-
return __io_import_fixed(req, rw, iter, imu);
3078+
if (WARN_ON_ONCE(!req->imu))
3079+
return -EFAULT;
3080+
return __io_import_fixed(req, rw, iter, req->imu);
30813081
}
30823082

30833083
static void io_ring_submit_unlock(struct io_ring_ctx *ctx, bool needs_lock)

0 commit comments

Comments
 (0)