6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Longlong Xia [ Upstream commit c1dd5e24a82d19bff8eef50ba8205d4776584aff ] zswap_setup() publishes the pool on the zswap_pools list with a plain list_add(), but the list is walked by concurrent RCU readers holding nothing but rcu_read_lock() through zswap_total_pages(), e.g. /proc/meminfo and the shrinker count path. CPU 0 (writer) CPU 1 (reader) -------------- -------------- zswap_pool_create(): pool->zs_pool = zs_create_pool(); (1) list_add() -> __list_add(): WRITE_ONCE(zswap_pools.next, &pool->list); (2) zswap_total_pages(): pool = READ_ONCE( (a) zswap_pools.next); zs_get_total_pages( (b) pool->zs_pool); If (2) becomes visible to CPU 1 before (1), CPU 1 finds the pool at (a) but dereferences a wild pointer at (b). Publish the node with list_add_rcu(). Link: https://lore.kernel.org/20260908012801.1864430-1-xialonglong2025@163.com Fixes: 91cdcd8d624b ("mm: zswap: optimize zswap pool size tracking") Signed-off-by: Longlong Xia Signed-off-by: Andrew Morton Reported-by: Sashiko Closes: https://sashiko.dev/#/patchset/20260906133601.3563324-1-xialonglong2025%40163.com Acked-by: Yosry Ahmed Acked-by: Nhat Pham Assisted-by: Zcode:GLM-5.3 Cc: Chengming Zhou Cc: Johannes Weiner Cc: Signed-off-by: Sasha Levin --- mm/zswap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/zswap.c b/mm/zswap.c index 18249dd96ef86..e4b2f6abefafb 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -1818,7 +1818,7 @@ static int zswap_setup(void) pool = __zswap_pool_create_fallback(); if (pool) { pr_info("loaded using pool %s\n", pool->tfm_name); - list_add(&pool->list, &zswap_pools); + list_add_rcu(&pool->list, &zswap_pools); zswap_has_pool = true; static_branch_enable(&zswap_ever_enabled); } else { -- 2.53.0