* [PATCH 1/3] io_uring: fix pinned pages and pages array leak in io_region_pin_pages()
2026-04-08 6:54 [PATCH 0/3] io_uring: fix resource leak issues KobaK
@ 2026-04-08 6:54 ` KobaK
2026-04-08 8:34 ` Pavel Begunkov
2026-04-08 6:54 ` [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path KobaK
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: KobaK @ 2026-04-08 6:54 UTC (permalink / raw)
To: Jens Axboe, Pavel Begunkov
Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel, Koba Ko
From: Koba Ko <kobak@nvidia.com>
When io_pin_pages() succeeds but the subsequent nr_pages sanity check
fires (WARN_ON_ONCE), the function returns -EFAULT without unpinning the
user pages or freeing the kvmalloc'd pages array. The caller's cleanup
via io_free_region() won't help either, because mr->pages was never
assigned — so the entire cleanup block is skipped.
Add unpin_user_pages() and kvfree() before the error return to prevent
the leak.
Fixes: a90558b36ccee ("io_uring/memmap: helper for pinning region pages")
Signed-off-by: Koba Ko <kobak@nvidia.com>
---
io_uring/memmap.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/io_uring/memmap.c b/io_uring/memmap.c
index e6958968975a8..9f0d3750ce3bc 100644
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -141,8 +141,11 @@ static int io_region_pin_pages(struct io_mapped_region *mr,
pages = io_pin_pages(reg->user_addr, size, &nr_pages);
if (IS_ERR(pages))
return PTR_ERR(pages);
- if (WARN_ON_ONCE(nr_pages != mr->nr_pages))
+ if (WARN_ON_ONCE(nr_pages != mr->nr_pages)) {
+ unpin_user_pages(pages, nr_pages);
+ kvfree(pages);
return -EFAULT;
+ }
mr->pages = pages;
mr->flags |= IO_REGION_F_USER_PROVIDED;
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/3] io_uring: fix pinned pages and pages array leak in io_region_pin_pages()
2026-04-08 6:54 ` [PATCH 1/3] io_uring: fix pinned pages and pages array leak in io_region_pin_pages() KobaK
@ 2026-04-08 8:34 ` Pavel Begunkov
0 siblings, 0 replies; 9+ messages in thread
From: Pavel Begunkov @ 2026-04-08 8:34 UTC (permalink / raw)
To: KobaK, Jens Axboe; +Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel
On 4/8/26 07:54, KobaK wrote:
> From: Koba Ko <kobak@nvidia.com>
>
> When io_pin_pages() succeeds but the subsequent nr_pages sanity check
> fires (WARN_ON_ONCE), the function returns -EFAULT without unpinning the
> user pages or freeing the kvmalloc'd pages array. The caller's cleanup
> via io_free_region() won't help either, because mr->pages was never
> assigned — so the entire cleanup block is skipped.
>
> Add unpin_user_pages() and kvfree() before the error return to prevent
> the leak.
>
> Fixes: a90558b36ccee ("io_uring/memmap: helper for pinning region pages")
> Signed-off-by: Koba Ko <kobak@nvidia.com>
It's a WARN path, it should never happen, but if it does, that means
io_pin_pages() is buggy, and it's better to leak rather than risk
something nastier.
> ---
> io_uring/memmap.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/io_uring/memmap.c b/io_uring/memmap.c
> index e6958968975a8..9f0d3750ce3bc 100644
> --- a/io_uring/memmap.c
> +++ b/io_uring/memmap.c
> @@ -141,8 +141,11 @@ static int io_region_pin_pages(struct io_mapped_region *mr,
> pages = io_pin_pages(reg->user_addr, size, &nr_pages);
> if (IS_ERR(pages))
> return PTR_ERR(pages);
> - if (WARN_ON_ONCE(nr_pages != mr->nr_pages))
> + if (WARN_ON_ONCE(nr_pages != mr->nr_pages)) {
> + unpin_user_pages(pages, nr_pages);
> + kvfree(pages);
> return -EFAULT;
> + }
>
> mr->pages = pages;
> mr->flags |= IO_REGION_F_USER_PROVIDED;
--
Pavel Begunkov
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path
2026-04-08 6:54 [PATCH 0/3] io_uring: fix resource leak issues KobaK
2026-04-08 6:54 ` [PATCH 1/3] io_uring: fix pinned pages and pages array leak in io_region_pin_pages() KobaK
@ 2026-04-08 6:54 ` KobaK
2026-04-08 8:35 ` Pavel Begunkov
2026-04-08 6:54 ` [PATCH 3/3] io_uring/zcrx: fix resource leak and double-free hazard in io_import_umem KobaK
2026-04-08 12:51 ` [PATCH 0/3] io_uring: fix resource leak issues Jens Axboe
3 siblings, 1 reply; 9+ messages in thread
From: KobaK @ 2026-04-08 6:54 UTC (permalink / raw)
To: Jens Axboe, Pavel Begunkov
Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel, Koba Ko
From: Koba Ko <kobak@nvidia.com>
io_buffer_register_bvec() allocates the rsrc node via
io_rsrc_node_alloc() which pulls from ctx->node_cache. On imu allocation
failure, the node is freed with raw kfree() instead of
io_cache_free(&ctx->node_cache, node), bypassing the cache return path
and wasting a reuse opportunity. Every other error path in this file
correctly uses io_cache_free for nodes.
Fixes: 27cb27b6d5ea4 ("io_uring: add support for kernel registered bvecs")
Signed-off-by: Koba Ko <kobak@nvidia.com>
---
io_uring/rsrc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 1b96ab5e98c99..6f46cf9cd13d7 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -961,7 +961,7 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
*/
imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
if (!imu) {
- kfree(node);
+ io_cache_free(&ctx->node_cache, node);
ret = -ENOMEM;
goto unlock;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path
2026-04-08 6:54 ` [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path KobaK
@ 2026-04-08 8:35 ` Pavel Begunkov
2026-04-08 12:49 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2026-04-08 8:35 UTC (permalink / raw)
To: KobaK, Jens Axboe; +Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel
On 4/8/26 07:54, KobaK wrote:
> From: Koba Ko <kobak@nvidia.com>
>
> io_buffer_register_bvec() allocates the rsrc node via
> io_rsrc_node_alloc() which pulls from ctx->node_cache. On imu allocation
> failure, the node is freed with raw kfree() instead of
> io_cache_free(&ctx->node_cache, node), bypassing the cache return path
> and wasting a reuse opportunity. Every other error path in this file
> correctly uses io_cache_free for nodes.
>
> Fixes: 27cb27b6d5ea4 ("io_uring: add support for kernel registered bvecs")
> Signed-off-by: Koba Ko <kobak@nvidia.com>
> ---
> io_uring/rsrc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
> index 1b96ab5e98c99..6f46cf9cd13d7 100644
> --- a/io_uring/rsrc.c
> +++ b/io_uring/rsrc.c
> @@ -961,7 +961,7 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
> */
> imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
> if (!imu) {
> - kfree(node);
> + io_cache_free(&ctx->node_cache, node);
Looks like it was already patched a week ago
--
Pavel Begunkov
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path
2026-04-08 8:35 ` Pavel Begunkov
@ 2026-04-08 12:49 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-04-08 12:49 UTC (permalink / raw)
To: Pavel Begunkov, KobaK
Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel
On 4/8/26 2:35 AM, Pavel Begunkov wrote:
> On 4/8/26 07:54, KobaK wrote:
>> From: Koba Ko <kobak@nvidia.com>
>>
>> io_buffer_register_bvec() allocates the rsrc node via
>> io_rsrc_node_alloc() which pulls from ctx->node_cache. On imu allocation
>> failure, the node is freed with raw kfree() instead of
>> io_cache_free(&ctx->node_cache, node), bypassing the cache return path
>> and wasting a reuse opportunity. Every other error path in this file
>> correctly uses io_cache_free for nodes.
>>
>> Fixes: 27cb27b6d5ea4 ("io_uring: add support for kernel registered bvecs")
>> Signed-off-by: Koba Ko <kobak@nvidia.com>
>> ---
>> io_uring/rsrc.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
>> index 1b96ab5e98c99..6f46cf9cd13d7 100644
>> --- a/io_uring/rsrc.c
>> +++ b/io_uring/rsrc.c
>> @@ -961,7 +961,7 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
>> */
>> imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
>> if (!imu) {
>> - kfree(node);
>> + io_cache_free(&ctx->node_cache, node);
>
> Looks like it was already patched a week ago
Indeed, and main motivation was to eliminate reports like this, where
(clearly) an LLM spotted the "problem" even if there is none. Guess that
was a good move, just need it to land so that we don't need to waste
time on this again.
Nobody cares about "wasting a reuse opportunity" in an error path, any
human would recognize that.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] io_uring/zcrx: fix resource leak and double-free hazard in io_import_umem
2026-04-08 6:54 [PATCH 0/3] io_uring: fix resource leak issues KobaK
2026-04-08 6:54 ` [PATCH 1/3] io_uring: fix pinned pages and pages array leak in io_region_pin_pages() KobaK
2026-04-08 6:54 ` [PATCH 2/3] io_uring/rsrc: use io_cache_free for node in io_buffer_register_bvec error path KobaK
@ 2026-04-08 6:54 ` KobaK
2026-04-08 9:06 ` Pavel Begunkov
2026-04-08 12:51 ` [PATCH 0/3] io_uring: fix resource leak issues Jens Axboe
3 siblings, 1 reply; 9+ messages in thread
From: KobaK @ 2026-04-08 6:54 UTC (permalink / raw)
To: Jens Axboe, Pavel Begunkov
Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel, Koba Ko
From: Koba Ko <kobak@nvidia.com>
io_import_umem() has two problems:
1. When io_account_mem() fails, the function returns an error but leaves
live pinned pages and sg_table in the mem struct without cleaning them
up. The caller happens to handle this today via io_zcrx_free_area() ->
io_release_area_mem(), but the contract is fragile.
2. io_release_area_mem() doesn't NULL out mem->pages after kvfree(),
making it unsafe to call twice. Since io_zcrx_free_area() always
calls it during teardown, any earlier cleanup call would cause a
double-free.
Fix both: populate mem fields before io_account_mem() so
io_release_area_mem() can do a proper cleanup on failure, and add
mem->pages = NULL in io_release_area_mem() to make it idempotent.
Fixes: 262ab205180d2 ("io_uring/zcrx: account area memory")
Signed-off-by: Koba Ko <kobak@nvidia.com>
---
io_uring/zcrx.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index 62d693287457f..c9ed1139c7bcd 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -188,6 +188,8 @@ static unsigned long io_count_account_pages(struct page **pages, unsigned nr_pag
return res;
}
+static void io_release_area_mem(struct io_zcrx_mem *mem);
+
static int io_import_umem(struct io_zcrx_ifq *ifq,
struct io_zcrx_mem *mem,
struct io_uring_zcrx_area_reg *area_reg)
@@ -213,16 +215,20 @@ static int io_import_umem(struct io_zcrx_ifq *ifq,
return ret;
}
- mem->account_pages = io_count_account_pages(pages, nr_pages);
- ret = io_account_mem(ifq->user, ifq->mm_account, mem->account_pages);
- if (ret < 0)
- mem->account_pages = 0;
-
mem->sgt = &mem->page_sg_table;
mem->pages = pages;
mem->nr_folios = nr_pages;
mem->size = area_reg->len;
- return ret;
+
+ mem->account_pages = io_count_account_pages(pages, nr_pages);
+ ret = io_account_mem(ifq->user, ifq->mm_account, mem->account_pages);
+ if (ret < 0) {
+ mem->account_pages = 0;
+ io_release_area_mem(mem);
+ return ret;
+ }
+
+ return 0;
}
static void io_release_area_mem(struct io_zcrx_mem *mem)
@@ -236,6 +242,7 @@ static void io_release_area_mem(struct io_zcrx_mem *mem)
sg_free_table(mem->sgt);
mem->sgt = NULL;
kvfree(mem->pages);
+ mem->pages = NULL;
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 3/3] io_uring/zcrx: fix resource leak and double-free hazard in io_import_umem
2026-04-08 6:54 ` [PATCH 3/3] io_uring/zcrx: fix resource leak and double-free hazard in io_import_umem KobaK
@ 2026-04-08 9:06 ` Pavel Begunkov
0 siblings, 0 replies; 9+ messages in thread
From: Pavel Begunkov @ 2026-04-08 9:06 UTC (permalink / raw)
To: KobaK, Jens Axboe; +Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel
On 4/8/26 07:54, KobaK wrote:
> From: Koba Ko <kobak@nvidia.com>
>
> io_import_umem() has two problems:
>
> 1. When io_account_mem() fails, the function returns an error but leaves
> live pinned pages and sg_table in the mem struct without cleaning them
> up. The caller happens to handle this today via io_zcrx_free_area() ->
> io_release_area_mem(), but the contract is fragile.
That was the intention for the caller to clean it up, but in either
case the function has already been rewritten. In general, it seems
you based your patches on top of an outdated tree.
> 2. io_release_area_mem() doesn't NULL out mem->pages after kvfree(),
> making it unsafe to call twice. Since io_zcrx_free_area() always
> calls it during teardown, any earlier cleanup call would cause a
> double-free.
>
> Fix both: populate mem fields before io_account_mem() so
> io_release_area_mem() can do a proper cleanup on failure, and add
> mem->pages = NULL in io_release_area_mem() to make it idempotent.
>
> Fixes: 262ab205180d2 ("io_uring/zcrx: account area memory")
> Signed-off-by: Koba Ko <kobak@nvidia.com>
> ---
...
>
> static void io_release_area_mem(struct io_zcrx_mem *mem)
> @@ -236,6 +242,7 @@ static void io_release_area_mem(struct io_zcrx_mem *mem)
> sg_free_table(mem->sgt);
> mem->sgt = NULL;
> kvfree(mem->pages);
> + mem->pages = NULL;
The entire struct io_zcrx_mem / area is freed right after,
calling io_zcrx_free_area() multiple times for the same area
is not allowed.
--
Pavel Begunkov
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] io_uring: fix resource leak issues
2026-04-08 6:54 [PATCH 0/3] io_uring: fix resource leak issues KobaK
` (2 preceding siblings ...)
2026-04-08 6:54 ` [PATCH 3/3] io_uring/zcrx: fix resource leak and double-free hazard in io_import_umem KobaK
@ 2026-04-08 12:51 ` Jens Axboe
3 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-04-08 12:51 UTC (permalink / raw)
To: KobaK, Pavel Begunkov
Cc: Keith Busch, Ming Lei, io-uring, netdev, linux-kernel
On 4/8/26 12:54 AM, KobaK wrote:
> From: Koba Ko <kobak@nvidia.com>
>
> Three resource leak fixes found by code audit:
>
> 1. memmap: pinned pages and pages array leak on WARN_ON path in
> io_region_pin_pages() ? mr->pages is never assigned so the caller's
> cleanup is a no-op.
>
> 2. rsrc: kfree() used instead of io_cache_free() in
> io_buffer_register_bvec() error path ? bypasses cache return.
>
> 3. zcrx: io_import_umem() leaves live pinned pages in a partially
> initialized struct on io_account_mem() failure, and
> io_release_area_mem() is not idempotent (missing pages = NULL),
> creating a double-free hazard.
General advice - anyone can point an LLM at a code base and get some
reports, but please apply some actual critical thinking to the "issues"
found before blindly sending them out.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread