Skip to content

Commit 8802766

Browse files
isilenceaxboe
authored andcommitted
io_uring/kbuf: reallocate buf lists on upgrade
IORING_REGISTER_PBUF_RING can reuse an old struct io_buffer_list if it was created for legacy selected buffer and has been emptied. It violates the requirement that most of the field should stay stable after publish. Always reallocate it instead. Cc: stable@vger.kernel.org Reported-by: Pumpkin Chang <pumpkin@devco.re> Fixes: 2fcabce ("io_uring: disallow mixed provided buffer group registrations") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 06521ac commit 8802766

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

io_uring/kbuf.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,13 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)
415415
}
416416
}
417417

418+
static void io_destroy_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl)
419+
{
420+
scoped_guard(mutex, &ctx->mmap_lock)
421+
WARN_ON_ONCE(xa_erase(&ctx->io_bl_xa, bl->bgid) != bl);
422+
io_put_bl(ctx, bl);
423+
}
424+
418425
int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
419426
{
420427
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
@@ -636,12 +643,13 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
636643
/* if mapped buffer ring OR classic exists, don't allow */
637644
if (bl->flags & IOBL_BUF_RING || !list_empty(&bl->buf_list))
638645
return -EEXIST;
639-
} else {
640-
free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
641-
if (!bl)
642-
return -ENOMEM;
646+
io_destroy_bl(ctx, bl);
643647
}
644648

649+
free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
650+
if (!bl)
651+
return -ENOMEM;
652+
645653
mmap_offset = (unsigned long)reg.bgid << IORING_OFF_PBUF_SHIFT;
646654
ring_size = flex_array_size(br, bufs, reg.ring_entries);
647655

0 commit comments

Comments
 (0)