mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
io_uring: fix physical SQE bounds check for SQE_MIXED 128-byte ops
When IORING_SETUP_SQE_MIXED is used without IORING_SETUP_NO_SQARRAY,
the boundary check for 128-byte SQE operations in io_init_req()
validated the logical SQ head position rather than the physical SQE
index.
The existing check:
!(ctx->cached_sq_head & (ctx->sq_entries - 1))
ensures the logical position isn't at the end of the ring, which is
correct for NO_SQARRAY rings where physical == logical. However, when
sq_array is present, an unprivileged user can remap any logical
position to an arbitrary physical index via sq_array. Setting
sq_array[N] = sq_entries - 1 places a 128-byte operation at the last
physical SQE slot, causing the 128-byte memcpy in
io_uring_cmd_sqe_copy() to read 64 bytes past the end of the SQE
array.
Replace the cached_sq_head alignment check with a direct validation
of the physical SQE index, which correctly handles both sq_array and
NO_SQARRAY cases.
Fixes: 1cba30bf9f ("io_uring: add support for IORING_SETUP_SQE_MIXED")
Signed-off-by: Tom Ryan <ryan36005@gmail.com>
Link: https://patch.msgid.link/20260310052003.72871-1-ryan36005@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -1745,7 +1745,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
|
||||
* well as 2 contiguous entries.
|
||||
*/
|
||||
if (!(ctx->flags & IORING_SETUP_SQE_MIXED) || *left < 2 ||
|
||||
!(ctx->cached_sq_head & (ctx->sq_entries - 1)))
|
||||
(unsigned)(sqe - ctx->sq_sqes) >= ctx->sq_entries - 1)
|
||||
return io_init_fail_req(req, -EINVAL);
|
||||
/*
|
||||
* A 128b operation on a mixed SQ uses two entries, so we have
|
||||
|
||||
Reference in New Issue
Block a user