diff options
| author | Mina Almasry <almasrymina@google.com> | 2026-09-25 14:41:11 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-09-28 18:24:05 -0700 |
| commit | bdea4980182e3badac74f04df6c07492b91c569e (patch) | |
| tree | 8b4db610e97d14879e3ce22a73363a883337a462 /net/core | |
| parent | 512ccd3d0e91e791fb37442aa0a2599aca19783d (diff) | |
| download | linux-next-bdea4980182e3badac74f04df6c07492b91c569e.tar.gz linux-next-bdea4980182e3badac74f04df6c07492b91c569e.zip | |
net: page_pool: fix use-after-free in page_pool_recycle_ring_bulk()
With CONFIG_PAGE_POOL_STATS=y, page_pool_recycle_ring_bulk() updates
the recycle stats after dropping the producer lock. If it just recycled
the last inflight netmems of a pool being destroyed, page_pool_release()
can pass its producer-lock barrier and free the pool before
recycle_stat_add() runs.
Commit fcc680a647ba7 ("page_pool: allow mixing PPs within one bulk")
moved this stat update after the unlock. Commit 271683bb2cf32
("page_pool: Fix use-after-free in page_pool_recycle_in_ring") later
added the barrier, but only fixed page_pool_recycle_in_ring(). Move
the update back under the lock.
Fixes: fcc680a647ba7 ("page_pool: allow mixing PPs within one bulk")
Link: https://lore.kernel.org/r/179028939171.2160803.706522228583664641@kernel.org
Cc: Kaifeng Wang <kaifengw@google.com>
Cc: Dong Chenchen <dongchenchen2@huawei.com>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20260925144127.1445667-1-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/page_pool.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 08d7f35cf608..d7c88c0b67e5 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -951,8 +951,8 @@ static void page_pool_recycle_ring_bulk(struct page_pool *pool, } } - page_pool_producer_unlock(pool, in_softirq); recycle_stat_add(pool, ring, i); + page_pool_producer_unlock(pool, in_softirq); /* Hopefully all pages were returned into ptr_ring */ if (likely(i == bulk_len)) |
