Skip to content

Commit 8b51a39

Browse files
committed
io_uring: fix crash with IORING_SETUP_NO_MMAP and invalid SQ ring address
If we specify a valid CQ ring address but an invalid SQ ring address, we'll correctly spot this and free the allocated pages and clear them to NULL. However, we don't clear the ring page count, and hence will attempt to free the pages again. We've already cleared the address of the page array when freeing them, but we don't check for that. This causes the following crash: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Oops [#1] Modules linked in: CPU: 0 PID: 20 Comm: kworker/u2:1 Not tainted 6.6.0-rc5-dirty #56 Hardware name: ucbbar,riscvemu-bare (DT) Workqueue: events_unbound io_ring_exit_work epc : io_pages_free+0x2a/0x58 ra : io_rings_free+0x3a/0x50 epc : ffffffff808811a2 ra : ffffffff80881406 sp : ffff8f80000c3cd0 status: 0000000200000121 badaddr: 0000000000000000 cause: 000000000000000d [<ffffffff808811a2>] io_pages_free+0x2a/0x58 [<ffffffff80881406>] io_rings_free+0x3a/0x50 [<ffffffff80882176>] io_ring_exit_work+0x37e/0x424 [<ffffffff80027234>] process_one_work+0x10c/0x1f4 [<ffffffff8002756e>] worker_thread+0x252/0x31c [<ffffffff8002f5e4>] kthread+0xc4/0xe0 [<ffffffff8000332a>] ret_from_fork+0xa/0x1c Check for a NULL array in io_pages_free(), but also clear the page counts when we free them to be on the safer side. Reported-by: [email protected] Fixes: 03d89a2 ("io_uring: support for user allocated memory for rings/sqes") Cc: [email protected] Reviewed-by: Jeff Moyer <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 0f8baa3 commit 8b51a39

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

io_uring/io_uring.c

+6
Original file line numberDiff line numberDiff line change
@@ -2674,7 +2674,11 @@ static void io_pages_free(struct page ***pages, int npages)
26742674

26752675
if (!pages)
26762676
return;
2677+
26772678
page_array = *pages;
2679+
if (!page_array)
2680+
return;
2681+
26782682
for (i = 0; i < npages; i++)
26792683
unpin_user_page(page_array[i]);
26802684
kvfree(page_array);
@@ -2758,7 +2762,9 @@ static void io_rings_free(struct io_ring_ctx *ctx)
27582762
ctx->sq_sqes = NULL;
27592763
} else {
27602764
io_pages_free(&ctx->ring_pages, ctx->n_ring_pages);
2765+
ctx->n_ring_pages = 0;
27612766
io_pages_free(&ctx->sqe_pages, ctx->n_sqe_pages);
2767+
ctx->n_sqe_pages = 0;
27622768
}
27632769
}
27642770

0 commit comments

Comments
 (0)