summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2025-01-15 15:39:12 +0100
committerJens Axboe <axboe@kernel.dk>2025-01-15 15:45:47 +0100
commit8911798d3e8a9624b1acf2882c7a0183694d714d (patch)
tree62fbcec8da11210e3cd94596df5531630e38ae08
parentio_uring/rsrc: fixup io_clone_buffers() error handling (diff)
downloadlinux-8911798d3e8a9624b1acf2882c7a0183694d714d.tar.xz
linux-8911798d3e8a9624b1acf2882c7a0183694d714d.zip
io_uring/register: use stable SQ/CQ ring data during resize
Normally the kernel would not expect an application to modify any of the data shared with the kernel during a resize operation, but of course the kernel cannot always assume good intent on behalf of the application. As part of resizing the rings, existing SQEs and CQEs are copied over to the new storage. Resizing uses the masks in the newly allocated shared storage to index the arrays, however it's possible that malicious userspace could modify these after they have been sanity checked. Use the validated and locally stored CQ and SQ ring sizing for masking to ensure the values are both stable and valid. Fixes: 79cfe9e59c2a ("io_uring/register: add IORING_REGISTER_RESIZE_RINGS") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--io_uring/register.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/io_uring/register.c b/io_uring/register.c
index fdd44914c39c..5880eb75ae44 100644
--- a/io_uring/register.c
+++ b/io_uring/register.c
@@ -514,7 +514,7 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
goto overflow;
for (i = o.rings->sq.head; i < tail; i++) {
unsigned src_head = i & (ctx->sq_entries - 1);
- unsigned dst_head = i & n.rings->sq_ring_mask;
+ unsigned dst_head = i & (p.sq_entries - 1);
n.sq_sqes[dst_head] = o.sq_sqes[src_head];
}
@@ -533,7 +533,7 @@ overflow:
}
for (i = o.rings->cq.head; i < tail; i++) {
unsigned src_head = i & (ctx->cq_entries - 1);
- unsigned dst_head = i & n.rings->cq_ring_mask;
+ unsigned dst_head = i & (p.cq_entries - 1);
n.rings->cqes[dst_head] = o.rings->cqes[src_head];
}