Skip to content

[LTS 9.2] CVE-2025-38022, CVE-2025-38129#1387

Open
pvts-mat wants to merge 4 commits into
ctrliq:ciqlts9_2from
pvts-mat:CVE-batch-40_ciqlts9_2
Open

[LTS 9.2] CVE-2025-38022, CVE-2025-38129#1387
pvts-mat wants to merge 4 commits into
ctrliq:ciqlts9_2from
pvts-mat:CVE-batch-40_ciqlts9_2

Conversation

@pvts-mat

Copy link
Copy Markdown
Contributor

[LTS 9.2]

CVE-2025-38129 VULN-71838
CVE-2025-38022 VULN-71153

Commits

CVE-2025-38129

0:

page_pool: Fix use-after-free in page_pool_recycle_in_ring

jira VULN-71838
cve CVE-2025-38129
commit-author Dong Chenchen <dongchenchen2@huawei.com>
commit 271683bb2cf32e5126c592b5d5e6a756fa374fd9
upstream-diff Used linux-6.1.y backport
  1a8c0b61d4cb55c5440583ec9e7f86a730369e32 for a clean pick. It accounts
  for the similarly non-backported commit
  4dec64c52e24c2c9a15f81c115f1be5ea35121cb ("page_pool: convert to use
  netmem") and deals with the same context conflicts in
  `page_pool_release()'.

1:

page_pool: fix inconsistency for page_pool_ring_[un]lock()

jira VULN-71838
cve-pre CVE-2025-38129
commit-author Yunsheng Lin <linyunsheng@huawei.com>
commit 368d3cb406cdd074d1df2ad9ec06d1bfcb664882

This commit introduces page_pool_producer_lock() / page_pool_producer_unlock() functions on which the CVE-2025-38129 fix is based.

2:

net: page_pool: use in_softirq() instead

jira VULN-71838
cve-pre CVE-2025-38129
commit-author Qingfang DENG <qingfang.deng@siflower.com.cn>
commit 542bcea4be866b14b3a5c8e90773329066656c43

This prerequisite may not have been strictly necessary as the in_softirq()~/~in_serving_softirq() branching in page_pool_recycle_in_ring() is discarded in the CVE-2025-38129 fix anyway, but it simplifies patch backporting and is bugfix worthy of backporting in itself.

This solution is the same as in linux-6.1.y, with which LTS 9.2 has very similar net/core/page_pool.c history (=: same commit, ~: backported commit):

   File
   --------------------
   net/core/page_pool.c
   
   kernel-mainline                                                                                                   ciqlts9_2               linux-6.1.y           
   ---------------------------------------------------------------------------------------------------------------   ----------------------  ----------------------
   81a4d039537a89e 2026-05-28 net: make page_pool_get_stats() void
   ac0056e4f14b03e 2026-05-28 docs: page_pool: drop the mention of the legacy stats API
   54cf41c969da663 2026-05-21 Revert "mm: introduce a new page type for page pool in page type"
   5ef343614db766a 2026-04-29 page_pool: fix memory-provider leak in page_pool_create_percpu() error path                                                          
   db359fccf212e7f 2026-04-05 mm: introduce a new page type for page pool in page type
   9954464d737dd12 2025-12-02 net: page_pool: sanitise allocation order
   854858848bc7ac6 2025-12-02 net: page pool: xa init with destroy on pp init
   95920c2ed02bde5 2025-10-06 page_pool: Fix PP_MAGIC_MASK to avoid crashing on some 32-bit arches                                                                 
   a1b501a8c6a87c9 2025-09-30 page_pool: Clamp pool size to max 16K pages                                                                    ~ c5eb9ae97 2025-12-07
   f3b52167a0cb23b 2025-09-15 page_pool: always add GFP_NOWARN for ATOMIC allocations                                                        ~ 9835a0fd5 2025-12-07
   abadf0ff63be488 2025-08-22 page_pool: fix incorrect mp_ops error handling                                                                                       
   64fdaa94bfe0cca 2025-08-08 net: page_pool: allow enabling recycling late, fix false positive warning                                                            
   b56ce86846225d6 2025-07-07 page_pool: rename __page_pool_alloc_pages_slow() to __page_pool_alloc_netmems_slow()
   4ad125ae380bf0b 2025-07-07 page_pool: rename __page_pool_release_page_dma() to __page_pool_release_netmem_dma()
   61a33247533465c 2025-07-07 page_pool: rename page_pool_return_page() to page_pool_return_netmem()
0> 271683bb2cf32e5 2025-05-28 page_pool: Fix use-after-free in page_pool_recycle_in_ring                                                     ~ 1a8c0b61d 2026-01-11
   170ebc60b79a574 2025-05-27 page_pool: fix ugly page_pool formatting
   32471b2f481dea8 2025-05-15 net: page_pool: Don't recycle into cache on PREEMPT_RT                                                                               
   ee62ce7a1d909cc 2025-04-14 page_pool: Track DMA-mapped pages and unmap them when destroying the pool                                                            
   b52458652eca5a5 2025-03-25 net: protect rxq->mp_params with the instance lock                                                                                   
   43130d02baa1370 2025-02-18 page_pool: avoid infinite loop to schedule delayed worker                                                      ~ 90e089a64 2025-04-25
   c1e00bc4be06cac 2025-02-07 net: page_pool: avoid false positive warning if NAPI was never added                                                                 
   56102c013fa7b8d 2025-02-06 net: page_pool: add memory provider helpers                                                                                          
   [... no commits backported to either version...]
   2da0cac1e9494f3 2023-11-21 net: page_pool: avoid touching slow on the fastpath                                                                                  
   5027ec19f1049a0 2023-11-21 net: page_pool: split the page_pool_params into fast and slow                                                                        
   8ffbd1669ed1d58 2023-11-02 net: page_pool: add missing free_percpu when page_pool_init fail                                               ~ e129327d8 2023-11-20
   de97502e16fc406 2023-10-23 page_pool: introduce page_pool_alloc() API                                                                                           
   09d96ee5674a0ea 2023-10-23 page_pool: remove PP_FLAG_PAGE_FRAG                                                                                                  
   58d53d8f7da63dd 2023-10-23 page_pool: unify frag_count handling in page_pool_is_last_frag()                                                                     
   90de47f020db086 2023-10-16 page_pool: fragment API support for 32-bit arch with 64-bit DMA                                                                      
   ff4e538c8c3e675 2023-08-07 page_pool: add a lockdep check for recycling in hardirq                                                                              
   75eaf63ea7afeaf 2023-08-07 net: skbuff: don't include <net/page_pool/types.h> to <linux/skbuff.h>                                                               
   a9ca9f9ceff382b 2023-08-07 page_pool: split types and declarations from page_pool.h                                                                             
   82e896d992fa631 2023-08-03 docs: net: page_pool: use kdoc to avoid duplicating the information                                                                  
   07e0c7d3179da5d 2023-07-21 net: page_pool: merge page_pool_release_page() with page_pool_return_page()                                                          
   535b9c61bdef601 2023-07-21 net: page_pool: hide page_pool_release_page()                                                                                        
1> 368d3cb406cdd07 2023-05-23 page_pool: fix inconsistency for page_pool_ring_[un]lock()                                                     ~ 7c95f5699 2023-06-05
   dd64b232deb8d48 2023-04-20 page_pool: unlink from napi during destroy                                                                                           
   8e4c62c7d980eaf 2023-04-19 page_pool: add DMA_ATTR_WEAK_ORDERING on all mappings                                                                                
   8c48eea3adf3119 2023-04-14 page_pool: allow caching from safely localized NAPI                                                                                  
2> 542bcea4be866b1 2023-02-06 net: page_pool: use in_softirq() instead                                                                       ~ 7dccd5fa7 2023-06-05
   d810d367ec40a10 2022-07-07 net: page_pool: optimize page pool page allocation in NUMA scenario                    ~ 1cc26eafb 2023-01-05  = d810d367e 2022-07-07
   8d29c7036f5ff36 2022-07-03 mm/swap: convert __put_page() to __folio_put()                                                                 = 8d29c7036 2022-07-03
   0f6deac3a079581 2022-05-13 net: page_pool: add page allocation stats for two fast page allocate path              ~ 88509dacf 2022-11-30  = 0f6deac3a 2022-05-13
   f3c5264f452a5b0 2022-04-15 net: page_pool: introduce ethtool stats                                                ~ e4c225200 2022-11-30  = f3c5264f4 2022-04-15
   590032a4d2133ec 2022-04-12 page_pool: Add recycle stats to page_pool_put_page_bulk                                ~ 3c9b8c39b 2022-11-28  = 590032a4d 2022-04-12
   6b95e3388b1ea0c 2022-03-03 page_pool: Add function to batch and return stats                                      ~ b52705c25 2022-10-25  = 6b95e3388 2022-03-03
   ad6fa1e1ab1b816 2022-03-03 page_pool: Add recycle stats                                                           ~ 249dfc0fd 2022-10-25  = ad6fa1e1a 2022-03-03
   8610037e8106b48 2022-03-03 page_pool: Add allocation stats                                                        ~ ff8569059 2022-10-25  = 8610037e8 2022-03-03
   52cc6ffc0ab2c61 2022-02-03 page_pool: Refactor page_pool to enable fragmenting after allocation                   ~ 0700a9a4b 2022-10-25  = 52cc6ffc0 2022-02-03
   07b17f0f7485bcb 2022-01-09 page_pool: remove spinlock in page_pool_refill_alloc_cache()                           ~ 559e95e23 2022-08-24  = 07b17f0f7 2022-01-09
   64693ec7774e471 2022-01-05 page_pool: Store the XDP mem id                                                        ~ 9d38cafdb 2022-08-24  = 64693ec77 2022-01-05
   35b2e549894b7ef 2022-01-05 page_pool: Add callback to init pages when they are allocated                          ~ e33883538 2022-08-24  = 35b2e5498 2022-01-05
   f915b75bffb7257 2021-11-18 page_pool: Revert "page_pool: disable dma mapping support..."                                                  = f915b75bf 2021-11-18
   d00e60ee54b12de 2021-10-15 page_pool: disable dma mapping support for 32-bit arch with 64-bit DMA                                         = d00e60ee5 2021-10-15
   7fb9b66dc9ce52b 2021-08-24 page_pool: use relaxed atomic for release side accounting                              ~ 643fe5322 2022-05-12  = 7fb9b66dc 2021-08-24
   53e0961da1c7bbd 2021-08-09 page_pool: add frag page recycling support in page pool                                ~ 44b3ff853 2022-05-12  = 53e0961da 2021-08-09
   0e9d2a0a3a836c3 2021-08-09 page_pool: add interface to manipulate frag count in page pool                         ~ f60c1855e 2022-05-12  = 0e9d2a0a3 2021-08-09
   57f05bc2ab2443b 2021-08-09 page_pool: keep pp info as long as page pool owns the page                             ~ 2844f31ff 2022-05-12  = 57f05bc2a 2021-08-09
   0fa32ca438b42fa 2021-08-09 page_pool: mask the page->signature before the checking                                = 0fa32ca43 2021-08-09  = 0fa32ca43 2021-08-09
   6a5bcd84e886a9a 2021-06-07 page_pool: Allow drivers to hint on SKB recycling                                      = 6a5bcd84e 2021-06-07  = 6a5bcd84e 2021-06-07
   [... common git history ...]

CVE-2025-38022

RDMA/core: Fix "KASAN: slab-use-after-free Read in ib_register_device" problem

jira VULN-71153
cve CVE-2025-38022
commit-author Zhu Yanjun <yanjun.zhu@linux.dev>
commit d0706bfd3ee40923c001c6827b786a309e2a8713
upstream-diff Used linux-5.15.y backport
  5629064f92f0de6d6b3572055cd35361c3ad953c for the clean pick. In LTS
  9.2 the `ib_device_notify_register()' function, where the
  `kobject_uevent()' call wa moved in the upstream fix, doesn't exist.
  It was introduced in 9cbed5aab5aeea420d0aa945733bf608449d44fb
  ("RDMA/nldev: Add support for RDMA monitoring"), with locks put in
  place in 1d6a9e7449e2a0c1e2934eee7880ba8bd1e464cd ("RDMA/core: Fix
  use-after-free when rename device name"). Wrapping the
  `kobject_uevent()' call in `down_read(&devices_rwsem)' and
  `up_read(&devices_rwsem)' results in the same protection.

Since the fix looks completely different from upstream here's the breakdown of the issue. The fix message:

The root cause is: the function ib_device_rename() renames the name with
lock. But in the function kobject_uevent(), this name is accessed without
lock protection at the same time.

The solution is to add the lock protection when this name is accessed in
the function kobject_uevent().

The ib_device_rename() function:

int ib_device_rename(struct ib_device *ibdev, const char *name)
{
unsigned long index;
void *client_data;
int ret;
down_write(&devices_rwsem);
if (!strcmp(name, dev_name(&ibdev->dev))) {
up_write(&devices_rwsem);
return 0;
}
if (__ib_device_get_by_name(name)) {
up_write(&devices_rwsem);
return -EEXIST;
}
ret = device_rename(&ibdev->dev, name);
if (ret) {
up_write(&devices_rwsem);
return ret;
}
strscpy(ibdev->name, name, IB_DEVICE_NAME_MAX);
ret = rename_compat_devs(ibdev);
downgrade_write(&devices_rwsem);
down_read(&ibdev->client_data_rwsem);
xan_for_each_marked(&ibdev->client_data, index, client_data,
CLIENT_DATA_REGISTERED) {
struct ib_client *client = xa_load(&clients, index);
if (!client || !client->rename)
continue;
client->rename(ibdev, client_data);
}
up_read(&ibdev->client_data_rwsem);
rdma_nl_notify_event(ibdev, 0, RDMA_RENAME_EVENT);
up_read(&devices_rwsem);
return 0;
}

The lock is

down_write(&devices_rwsem);

and

up_read(&devices_rwsem);

The renaming appears in

client->rename(ibdev, client_data);

This is a function pointer of the struct ib_client structure

void (*rename)(struct ib_device *dev, void *client_data);

The only instance found in the codebase with this pointer set to non-null is srp_client:

static struct ib_client srp_client = {
.name = "srp",
.add = srp_add_one,
.remove = srp_remove_one,
.rename = srp_rename_dev
};

Definition:

static void srp_rename_dev(struct ib_device *device, void *client_data)
{
struct srp_device *srp_dev = client_data;
struct srp_host *host, *tmp_host;
list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) {
char name[IB_DEVICE_NAME_MAX + 8];
snprintf(name, sizeof(name), "srp-%s-%u",
dev_name(&device->dev), host->port);
device_rename(&host->dev, name);
}
}

Renaming takes place in device_rename(), using kobject_rename():

error = kobject_rename(kobj, new_name);

This function is a part of kernel's library for drivers, it operates on kobjects - core mechanism for reference-counted objects that organize system components into sysfs hierarchies and enable device hotplug notifications. This is the most likely free after which the use was done in kobject_uevent():

kfree_const(dup_name);

Tracking the KASAN stack trace from d0706bf's message it can be seen that the UAF occured in this line of the kobject_uevent_env() function (to which kobject_uevent() delegates with no additional logic):

devpath = kobject_get_path(kobj, GFP_KERNEL);

In the upstream the function was called here

/* Mark for userspace that device is ready */
kobject_uevent(&device->dev.kobj, KOBJ_ADD);

The d0706bf fix moved it inside the ib_device_notify_register() call appearing in the next line:

ib_device_notify_register(device);

/* Mark for userspace that device is ready */
kobject_uevent(&device->dev.kobj, KOBJ_ADD);

between

down_read(&devices_rwsem);

and

up_read(&devices_rwsem);

In LTS 9.2 this function doesn't exist, introduced in 9cbed5a, with locks put in place in 1d6a9e7. The latter is what was referenced in the CVE-2025-38022 fix commit's message

This problem is similar to the problem that the
commit 1d6a9e7 ("RDMA/core: Fix use-after-free when rename device name")
fixes.

Wrapping the kobject_uevent() call in down_read(&devices_rwsem) and up_read(&devices_rwsem) effetcively gives the same protection which was achieved in the upstream. The renaming function ib_device_rename() in LTS 9.2 doesn't differ much from the upstream and uses the same locks

int ib_device_rename(struct ib_device *ibdev, const char *name)
{
unsigned long index;
void *client_data;
int ret;
down_write(&devices_rwsem);
if (!strcmp(name, dev_name(&ibdev->dev))) {
up_write(&devices_rwsem);
return 0;
}
if (__ib_device_get_by_name(name)) {
up_write(&devices_rwsem);
return -EEXIST;
}
ret = device_rename(&ibdev->dev, name);
if (ret) {
up_write(&devices_rwsem);
return ret;
}
strlcpy(ibdev->name, name, IB_DEVICE_NAME_MAX);
ret = rename_compat_devs(ibdev);
downgrade_write(&devices_rwsem);
down_read(&ibdev->client_data_rwsem);
xan_for_each_marked(&ibdev->client_data, index, client_data,
CLIENT_DATA_REGISTERED) {
struct ib_client *client = xa_load(&clients, index);
if (!client || !client->rename)
continue;
client->rename(ibdev, client_data);
}
up_read(&ibdev->client_data_rwsem);
up_read(&devices_rwsem);
return 0;
}

kABI check: passed

[1/2] kabi_check_kernel	Check ABI of kernel [ciqlts9_2-CVE-batch-40]	_kabi_check_kernel__x86_64--test--ciqlts9_2-CVE-batch-40
+ dist_git_version=el-9.2
+ local_version=ciqlts9_2-CVE-batch-40
+ arch=x86_64
+ user=pvts
+ buildmachine=x86_64--build--ciqlts9_2
+ virsh_timeout=600
+ ssh_daemon_wait=20
+ src_dir=/mnt/code/kernel-dist-git-el-9.2
+ build_dir=/mnt/build_files/kernel-src-tree-ciqlts9_2-CVE-batch-40
+ sudo chmod +x /data/src/ctrliq-github-haskell/kernel-dist-git-el-9.2/SOURCES/check-kabi
+ ninja-back/virssh.xsh --max 8 --shutdown-on-success --shutdown-on-failure --timeout 600 --ssh-daemon-wait 20 pvts x86_64--build--ciqlts9_2 ''\''/mnt/code/kernel-dist-git-el-9.2/SOURCES/check-kabi'\'' -k '\''/mnt/code/kernel-dist-git-el-9.2/SOURCES/Module.kabi_x86_64'\'' -s '\''/mnt/build_files/kernel-src-tree-ciqlts9_2-CVE-batch-40/Module.symvers'\'''
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-batch-40/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

Reference

kselftests–ciqlts9_2–run1.log

Patch

kselftests–ciqlts9_2-CVE-batch-40–run1.log
kselftests–ciqlts9_2-CVE-batch-40–run2.log

Comparison

The tests results for the reference and the patch are the same.

$ ktests.xsh diff -d kselftests*.log

Column    File
--------  --------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2-CVE-batch-40--run1.log
Status2   kselftests--ciqlts9_2-CVE-batch-40--run2.log

full-test-results-comparison.log

pvts-mat added 4 commits June 28, 2026 18:12
…" problem

jira VULN-71153
cve CVE-2025-38022
commit-author Zhu Yanjun <yanjun.zhu@linux.dev>
commit d0706bf
upstream-diff Used linux-5.15.y backport
  5629064f92f0de6d6b3572055cd35361c3ad953c for the clean pick. In LTS
  9.2 the `ib_device_notify_register()' function, where the
  `kobject_uevent()' call wa moved in the upstream fix, doesn't exist.
  It was introduced in 9cbed5a
  ("RDMA/nldev: Add support for RDMA monitoring"), with locks put in
  place in 1d6a9e7 ("RDMA/core: Fix
  use-after-free when rename device name"). Wrapping the
  `kobject_uevent()' call in `down_read(&devices_rwsem)' and
  `up_read(&devices_rwsem)' results in the same protection.

Call Trace:

 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:408 [inline]
 print_report+0xc3/0x670 mm/kasan/report.c:521
 kasan_report+0xe0/0x110 mm/kasan/report.c:634
 strlen+0x93/0xa0 lib/string.c:420
 __fortify_strlen include/linux/fortify-string.h:268 [inline]
 get_kobj_path_length lib/kobject.c:118 [inline]
 kobject_get_path+0x3f/0x2a0 lib/kobject.c:158
 kobject_uevent_env+0x289/0x1870 lib/kobject_uevent.c:545
 ib_register_device drivers/infiniband/core/device.c:1472 [inline]
 ib_register_device+0x8cf/0xe00 drivers/infiniband/core/device.c:1393
 rxe_register_device+0x275/0x320 drivers/infiniband/sw/rxe/rxe_verbs.c:1552
 rxe_net_add+0x8e/0xe0 drivers/infiniband/sw/rxe/rxe_net.c:550
 rxe_newlink+0x70/0x190 drivers/infiniband/sw/rxe/rxe.c:225
 nldev_newlink+0x3a3/0x680 drivers/infiniband/core/nldev.c:1796
 rdma_nl_rcv_msg+0x387/0x6e0 drivers/infiniband/core/netlink.c:195
 rdma_nl_rcv_skb.constprop.0.isra.0+0x2e5/0x450
 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
 netlink_unicast+0x53a/0x7f0 net/netlink/af_netlink.c:1339
 netlink_sendmsg+0x8d1/0xdd0 net/netlink/af_netlink.c:1883
 sock_sendmsg_nosec net/socket.c:712 [inline]
 __sock_sendmsg net/socket.c:727 [inline]
 ____sys_sendmsg+0xa95/0xc70 net/socket.c:2566
 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2620
 __sys_sendmsg+0x16d/0x220 net/socket.c:2652
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

This problem is similar to the problem that the
commit 1d6a9e7 ("RDMA/core: Fix use-after-free when rename device name")
fixes.

The root cause is: the function ib_device_rename() renames the name with
lock. But in the function kobject_uevent(), this name is accessed without
lock protection at the same time.

The solution is to add the lock protection when this name is accessed in
the function kobject_uevent().

Fixes: 779e0bf ("RDMA/core: Do not indicate device ready when device enablement fails")
Link: https://patch.msgid.link/r/20250506151008.75701-1-yanjun.zhu@linux.dev
	Reported-by: syzbot+e2ce9e275ecc70a30b72@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e2ce9e275ecc70a30b72
	Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
	Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
(cherry picked from commit 5629064f92f0de6d6b3572055cd35361c3ad953c)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71838
cve-pre CVE-2025-38129
commit-author Qingfang DENG <qingfang.deng@siflower.com.cn>
commit 542bcea

We use BH context only for synchronization, so we don't care if it's
actually serving softirq or not.

As a side node, in case of threaded NAPI, in_serving_softirq() will
return false because it's in process context with BH off, making
page_pool_recycle_in_cache() unreachable.

	Signed-off-by: Qingfang DENG <qingfang.deng@siflower.com.cn>
	Tested-by: Felix Fietkau <nbd@nbd.name>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 542bcea)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71838
cve-pre CVE-2025-38129
commit-author Yunsheng Lin <linyunsheng@huawei.com>
commit 368d3cb

page_pool_ring_[un]lock() use in_softirq() to decide which
spin lock variant to use, and when they are called in the
context with in_softirq() being false, spin_lock_bh() is
called in page_pool_ring_lock() while spin_unlock() is
called in page_pool_ring_unlock(), because spin_lock_bh()
has disabled the softirq in page_pool_ring_lock(), which
causes inconsistency for spin lock pair calling.

This patch fixes it by returning in_softirq state from
page_pool_producer_lock(), and use it to decide which
spin lock variant to use in page_pool_producer_unlock().

As pool->ring has both producer and consumer lock, so
rename it to page_pool_producer_[un]lock() to reflect
the actual usage. Also move them to page_pool.c as they
are only used there, and remove the 'inline' as the
compiler may have better idea to do inlining or not.

Fixes: 7886244 ("net: page_pool: Add bulk support for ptr_ring")
	Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
	Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
	Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Link: https://lore.kernel.org/r/20230522031714.5089-1-linyunsheng@huawei.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 368d3cb)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71838
cve CVE-2025-38129
commit-author Dong Chenchen <dongchenchen2@huawei.com>
commit 271683b
upstream-diff Used linux-6.1.y backport
  1a8c0b61d4cb55c5440583ec9e7f86a730369e32 for a clean pick. It accounts
  for the similarly non-backported commit
  4dec64c ("page_pool: convert to use
  netmem") and deals with the same context conflicts in
  `page_pool_release()'.

syzbot reported a uaf in page_pool_recycle_in_ring:

BUG: KASAN: slab-use-after-free in lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862
Read of size 8 at addr ffff8880286045a0 by task syz.0.284/6943

CPU: 0 UID: 0 PID: 6943 Comm: syz.0.284 Not tainted 6.13.0-rc3-syzkaller-gdfa94ce54f41 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0x169/0x550 mm/kasan/report.c:489
 kasan_report+0x143/0x180 mm/kasan/report.c:602
 lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862
 __raw_spin_unlock_bh include/linux/spinlock_api_smp.h:165 [inline]
 _raw_spin_unlock_bh+0x1b/0x40 kernel/locking/spinlock.c:210
 spin_unlock_bh include/linux/spinlock.h:396 [inline]
 ptr_ring_produce_bh include/linux/ptr_ring.h:164 [inline]
 page_pool_recycle_in_ring net/core/page_pool.c:707 [inline]
 page_pool_put_unrefed_netmem+0x748/0xb00 net/core/page_pool.c:826
 page_pool_put_netmem include/net/page_pool/helpers.h:323 [inline]
 page_pool_put_full_netmem include/net/page_pool/helpers.h:353 [inline]
 napi_pp_put_page+0x149/0x2b0 net/core/skbuff.c:1036
 skb_pp_recycle net/core/skbuff.c:1047 [inline]
 skb_free_head net/core/skbuff.c:1094 [inline]
 skb_release_data+0x6c4/0x8a0 net/core/skbuff.c:1125
 skb_release_all net/core/skbuff.c:1190 [inline]
 __kfree_skb net/core/skbuff.c:1204 [inline]
 sk_skb_reason_drop+0x1c9/0x380 net/core/skbuff.c:1242
 kfree_skb_reason include/linux/skbuff.h:1263 [inline]
 __skb_queue_purge_reason include/linux/skbuff.h:3343 [inline]

root cause is:

page_pool_recycle_in_ring
  ptr_ring_produce
    spin_lock(&r->producer_lock);
    WRITE_ONCE(r->queue[r->producer++], ptr)
      //recycle last page to pool
				page_pool_release
				  page_pool_scrub
				    page_pool_empty_ring
				      ptr_ring_consume
				      page_pool_return_page  //release all page
				  __page_pool_destroy
				     free_percpu(pool->recycle_stats);
				     free(pool) //free

     spin_unlock(&r->producer_lock); //pool->ring uaf read
  recycle_stat_inc(pool, ring);

page_pool can be free while page pool recycle the last page in ring.
Add producer-lock barrier to page_pool_release to prevent the page
pool from being free before all pages have been recycled.

recycle_stat_inc() is empty when CONFIG_PAGE_POOL_STATS is not
enabled, which will trigger Wempty-body build warning. Add definition
for pool stat macro to fix warning.

	Suggested-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/netdev/20250513083123.3514193-1-dongchenchen2@huawei.com
Fixes: ff7d6b2 ("page_pool: refurbish version of page_pool code")
	Reported-by: syzbot+204a4382fcb3311f3858@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=204a4382fcb3311f3858
	Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
	Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
	Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250527114152.3119109-1-dongchenchen2@huawei.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 1a8c0b61d4cb55c5440583ec9e7f86a730369e32)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
@pvts-mat pvts-mat changed the title CVE batch 40 ciqlts9 2 [LTS 9.2] CVE-2025-38022, CVE-2025-38129 Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant