Skip to content

[LTS 8.6] CVE-2025-38085, CVE-2025-38022, CVE-2025-38129#1466

Draft
pvts-mat wants to merge 10 commits into
ctrliq:ciqlts8_6from
pvts-mat:CVE-batch-39_ciqlts8_6
Draft

[LTS 8.6] CVE-2025-38085, CVE-2025-38022, CVE-2025-38129#1466
pvts-mat wants to merge 10 commits into
ctrliq:ciqlts8_6from
pvts-mat:CVE-batch-39_ciqlts8_6

Conversation

@pvts-mat

Copy link
Copy Markdown
Contributor

[LTS 8.6]

CVE-2025-38085 VULN-71581
CVE-2025-38022 VULN-71148
CVE-2025-38129 VULN-71833

CVE-2025-38085

Situation

Commit 1013af4 mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race is identified as the fix for CVE-2025-38085. However, it depends on a function tlb_remove_table_sync_one which is not defined in LTS 8.6. It was introduced in 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE. No solution to CVE-2025-38085 was found which didn't have this commit in place:

  • centos9 12a6db3,
  • centos10 41f7eb5,
  • rocky9_6 2872192,
  • rocky8_10 e2c95cd,
  • rocky10_0 68b3612,
  • linux-5.10.y: 952596b08c74e8fe9e2883d1dc8a8f54a37384ec,
  • linux-5.15.y: a3d864c901a300c295692d129159fc3001a56185,
  • linux-6.1.y: b7754d3aa7bf9f62218d096c0c8f6c13698fac8b,
  • linux-6.6.y: fe684290418ef9ef76630072086ee530b92f02b8,
  • linux-6.12.y: 034a52b,
  • linux-6.15.y: a6bfeb97941a9187833b526bc6cc4ff5706d0ce9,

although also none of those solutions had 0d6e24d backported as part of it.

The commit 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE introduces a new option, but it's not user-selectable; rather, it's used in the configuration as part of architecture's features makeup, eg. as in (implied by):

select MMU_GATHER_RCU_TABLE_FREE

The commit therefore doesn't introduce a new feature but addresses the hardare setup not accounted for sufficiently before:

This however leaves architectures that don't have page based directories
but don't need RCU in a bind. For those, provide MMU_GATHER_TABLE_FREE,
which provides the independent batching for directories without the
additional RCU freeing.

Nevertheless backporting it may seem risky and simply ad-hoc defining the one line long tlb_remove_table_sync_one may be preferred. However, the definition of tlb_remove_table_sync_one function used in CVE-2025-38085 depends on an option. For CONFIG_MMU_GATHER_RCU_TABLE_FREE:

static void tlb_remove_table_sync_one(void)
{
/*
* This isn't an RCU grace period and hence the page-tables cannot be
* assumed to be actually RCU-freed.
*
* It is however sufficient for software page-table walkers that rely on
* IRQ disabling.
*/
smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
}

For !CONFIG_MMU_GATHER_RCU_TABLE_FREE:

static void tlb_remove_table_sync_one(void) { }

In the upstream the tlb_remove_table_one function is expressed by tlb_remove_table_sync_one:

static void tlb_remove_table_one(void *table)
{
tlb_remove_table_sync_one();
__tlb_remove_table(table);
}

If it was defined like that in LTS 8.6 as well then its definition would start depending on CONFIG_MMU_GATHER_RCU_TABLE_FREE too, which would change code semantics in an uncontrolled manner. Putting it under control by following 0d6e24d's options dependency would boil down to simply backporting that commit. Not expressing tlb_remove_table_one by tlb_remove_table_sync_one, on the other hand, would lead to code duplication and enigmatic deviation from the upstream. It was therefore decided to backport 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE despite some complications it implied.

That commit depends on options naming scheme not yet backported to LTS 8.6:

Old New Renaming ocmmit
`HAVE_RCU_TABLE_FREE` `MMU_GATHER_RCU_TABLE_FREE` ff2e6d7
`HAVE_MMU_GATHER_PAGE_SIZE` `MMU_GATHER_PAGE_SIZE` 3af4bd0
`HAVE_MMU_GATHER_NO_GATHER` `MMU_GATHER_NO_GATHER` 580a586
- `MMU_GATHER_TABLE_FREE` 0d6e24d

The renaming was done in a bulk, right before 0d6e24d:

git log --oneline -n 4 0d6e24d430ef23280d8dea0ba1faeefc66c26a57
0d6e24d430ef23280d8dea0ba1faeefc66c26a57 asm-generic/tlb: provide MMU_GATHER_TABLE_FREE
580a586c409ab3040b7284a19cd9e281692c40c7 asm-generic/tlb: rename HAVE_MMU_GATHER_NO_GATHER
3af4bd033759c4dab4f0ff594f0aa1e8d182b9d7 asm-generic/tlb: rename HAVE_MMU_GATHER_PAGE_SIZE
ff2e6d7259f82ccc9a5aaa7f41194161d9262392 asm-generic/tlb: rename HAVE_RCU_TABLE_FREE

Between sticking to an old scheme and using the new one the latter was chosen, because it made tha backporting much simpler, less prone to mistakes and it avoided devising a completely unique option name HAVE_MMU_GATHER_TABLE_FREE. Only the MMU_GATHER_NO_GATHER option was renamed though, to simplify the bug fix. This introduced some option naming inconsistency, but it's not a big problem.

All other commits in the CVE-2025-38085 fix are preparing the code for either the option renaming done in 580a586 asm-generic/tlb: rename HAVE_MMU_GATHER_NO_GATHER, or for prviding the MMU_GATHER_TABLE_FREE option with the required tlb_remove_table_sync_one function in 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE.

Finally, the CVE-2025-38085 fix 1013af4 mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race includes the exposition of tlb_remove_table_sync_one, which in the upstream was done in a similar fix 2ba99c5 mm/khugepaged: fix GUP-fast interaction by sending IPI, not backported to LTS 8.6.

Commits

mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race

jira VULN-71581
cve CVE-2025-38085
commit-author Jann Horn <jannh@google.com>
commit 1013af4f585fccc4d3e5c5824d174de2257f7d6d
upstream-diff |
  - Context conflicts due to missing
    59d9094df3d79443937add8700b2ef1a866b1081 ("mm: hugetlb: independent
    PMD page table shared count").
  - Exposed the `tlb_remove_table_sync_one' function for use in the
    solution (missing 2ba99c5e08812494bc57f319fb562f527d9bacd8
    ("mm/khugepaged: fix GUP-fast interaction by sending IPI")).

The CVE-2025-38085 fixing commit. Compared to the upstream the tlb_remove_table_sync_one function was made public as part of the fix.

asm-generic/tlb: provide MMU_GATHER_TABLE_FREE

jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit 0d6e24d430ef23280d8dea0ba1faeefc66c26a57
upstream-diff |
  include/asm-generic/tlb.h
        Small conflict in the comments
  mm/mmu_gather.c
        - Context conflict in tlb_flush_mmu_free because
          580a586c409ab3040b7284a19cd9e281692c40c7 ("asm-generic/tlb:
          rename HAVE_MMU_GATHER_NO_GATHER") wasn't backported and
          CONFIG_MMU_GATHER_NO_GATHER still has its old name
          CONFIG_HAVE_MMU_GATHER_NO_GATHER.
        - Context conflict in tlb_gather_mmu because
          3af4bd033759c4dab4f0ff594f0aa1e8d182b9d7 ("asm-generic/tlb:
          rename HAVE_MMU_GATHER_PAGE_SIZE") wasn't backported and
          CONFIG_MMU_GATHER_PAGE_SIZE still has its old name
          CONFIG_HAVE_MMU_GATHER_PAGE_SIZE.

This commit provides the necessary options for the tlb_remove_table_sync_one function to be defined properly. The new option MMU_GATHER_TABLE_FREE is not user-selectable and it doesn't introduce a new feature. Rather it can be thought of as fine-tuning the existing solution.

asm-generic/tlb: rename HAVE_RCU_TABLE_FREE

jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit ff2e6d7259f82ccc9a5aaa7f41194161d9262392
upstream-diff |
  arch/arm64/Kconfig
        Context conflicts due to options HAVE_FUTEX_CMPXCHG,
        HAVE_FUNCTION_ARG_ACCESS_API not yet introduced into LTS 8.6.
  arch/x86/Kconfig
        Context conflicts due to the option HAVE_RCU_TABLE_INVALIDATE
        still being in LTS 8.6, but no longer in the upstream

Code refactoring commit, functionally neutral. Backporting it significantly reduces conflict in backporting the main CVE-2025-38085 prerequisite 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE.

arm/tlb: Convert to generic mmu_gather

jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit b78180b97dcf667350aac716cd3f32356eaf4984

This commit massively simplifies the arch/arm/include/asm/tlb.h, easing the backport of 0d6e24d asm-generic/tlb: provide MMU_GATHER_TABLE_FREE. Important note from the commit's message:

No change in behavior intended.

ARM: Kconfig: remove useless parenthesis

jira VULN-71581
cve-pre CVE-2025-38085
commit-author Russell King <rmk+kernel@armlinux.org.uk>
commit f00790aaf2e240f57d19dab39e07f0ab87c6d95c

Similarly to the commit above this one prepares the codebase for the cherry pick of ff2e6d7 asm-generic/tlb: rename HAVE_RCU_TABLE_FREE. Functionally neutral.

arm/asm/tlb.h: Fix build error implicit func declaration

jira VULN-71581
cve-pre CVE-2025-38085
commit-author Anders Roxell <anders.roxell@linaro.org>
commit 063daa8129f94d651c4d30a8333b577c5bbf8090

This commit is just a small and cheap prerequisite to make clean the cherry pick of b78180b arm/tlb: Convert to generic mmu_gather. Functionally neutral.

CVE-2025-38022

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

jira VULN-71148
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 8.6
  the `ib_device_notify_register()' function, where the `kobject_uevent()'
  call was 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.

For details see the explanation of the solution to LTS 9.2 (same situation)

CVE-2025-38129

page_pool: Fix use-after-free in page_pool_recycle_in_ring

jira VULN-71833
cve CVE-2025-38129
commit-author Dong Chenchen <dongchenchen2@huawei.com>
commit 271683bb2cf32e5126c592b5d5e6a756fa374fd9
upstream-diff Used linux-5.15.y backport
  d69f28ef7cdafdcf37ee310f38b1399e7d05f9a8 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()', as well as with the multiple context conflicts
  before the `page_pool_producer_lock()' definition (mostly non-
  backported stats functionality).
page_pool: fix inconsistency for page_pool_ring_[un]lock()

jira VULN-71833
cve-pre CVE-2025-38129
commit-author Yunsheng Lin <linyunsheng@huawei.com>
commit 368d3cb406cdd074d1df2ad9ec06d1bfcb664882
upstream-diff Context conflicts resolved, no actual diffs from the
  upstream
net: page_pool: use in_softirq() instead

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

For details see the explanation of the solution to LTS 9.2 (similar situation)

kABI check: passed

[0/1] kabi_check_kernel	Check ABI of kernel [ciqlts8_6-CVE-batch-39]	_kabi_check_kernel__x86_64--test--ciqlts8_6-CVE-batch-39
ninja explain: output state/kernels/ciqlts8_6-CVE-batch-39/x86_64/kabi_checked doesn't exist
ninja explain: state/kernels/ciqlts8_6-CVE-batch-39/x86_64/kabi_checked is dirty
+ dist_git_version=el-8.6
+ local_version=ciqlts8_6-CVE-batch-39
+ arch=x86_64
+ user=pvts
+ buildmachine=x86_64--build--ciqlts8_6
+ virsh_timeout=600
+ ssh_daemon_wait=20
+ src_dir=/mnt/code/kernel-dist-git-el-8.6
+ build_dir=/mnt/build_files/kernel-src-tree-ciqlts8_6-CVE-batch-39
+ sudo chmod +x /data/src/ctrliq-github-haskell/kernel-dist-git-el-8.6/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--ciqlts8_6 ''\''/mnt/code/kernel-dist-git-el-8.6/SOURCES/check-kabi'\'' -k '\''/mnt/code/kernel-dist-git-el-8.6/SOURCES/Module.kabi_x86_64'\'' -s '\''/mnt/build_files/kernel-src-tree-ciqlts8_6-CVE-batch-39/Module.symvers'\'''
kABI check passed
+ touch state/kernels/ciqlts8_6-CVE-batch-39/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed rleative

Reference

kselftests–ciqlts8_6–run1.log

Patch

kselftests–ciqlts8_6-CVE-batch-39–run1.log

Comparison

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

$ ktests.xsh diff -d kselftests*.log

Column    File
--------  --------------------------------------------
Status0   kselftests--ciqlts8_6--run1.log
Status1   kselftests--ciqlts8_6-CVE-batch-39--run1.log

full-test-results-comparison.log

pvts-mat added 10 commits July 22, 2026 18:19
…" problem

jira VULN-71148
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 8.6
  the `ib_device_notify_register()' function, where the `kobject_uevent()'
  call was 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-71833
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-71833
cve-pre CVE-2025-38129
commit-author Yunsheng Lin <linyunsheng@huawei.com>
commit 368d3cb
upstream-diff Context conflicts resolved, no actual diffs from the
  upstream

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-71833
cve CVE-2025-38129
commit-author Dong Chenchen <dongchenchen2@huawei.com>
commit 271683b
upstream-diff Used linux-5.15.y backport
  d69f28ef7cdafdcf37ee310f38b1399e7d05f9a8 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()', as well as with the multiple context conflicts
  before the `page_pool_producer_lock()' definition (mostly non-
  backported stats functionality).

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 d69f28ef7cdafdcf37ee310f38b1399e7d05f9a8)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve-pre CVE-2025-38085
commit-author Anders Roxell <anders.roxell@linaro.org>
commit 063daa8

Building on arm 32 with LPAE enabled we don't include asm-generic/tlb.h,
where we have tlb_flush_remove_tables_local and tlb_flush_remove_tables
defined.

The build fails with:

  mm/memory.c: In function ‘tlb_remove_table_smp_sync’:
  mm/memory.c:339:2: error: implicit declaration of function ‘tlb_flush_remove_tables_local’; did you mean ‘tlb_remove_table’? [-Werror=implicit-function-declaration]
  ...

This bug got introduced in:

  2ff6ddf ("x86/mm/tlb: Leave lazy TLB mode at page table free time")

To fix this issue we define them in arm 32's specific asm/tlb.h file as well.

	Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
	Cc: Linus Torvalds <torvalds@linux-foundation.org>
	Cc: Peter Zijlstra <peterz@infradead.org>
	Cc: Thomas Gleixner <tglx@linutronix.de>
	Cc: dave.hansen@intel.com
	Cc: linux-arm-kernel@lists.infradead.org
	Cc: linux@armlinux.org.uk
	Cc: riel@surriel.com
	Cc: songliubraving@fb.com
Fixes: 2ff6ddf ("x86/mm/tlb: Leave lazy TLB mode at page table free time")
Link: http://lkml.kernel.org/r/20180725095557.19668-1-anders.roxell@linaro.org
	Signed-off-by: Ingo Molnar <mingo@kernel.org>
(cherry picked from commit 063daa8)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve-pre CVE-2025-38085
commit-author Russell King <rmk+kernel@armlinux.org.uk>
commit f00790a

Remove useless parenthesis from the Kconfig - Kconfig is not C, and
can cope without parenthesising e.g. single symbols to 'if'.

	Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
(cherry picked from commit f00790a)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit b78180b

Generic mmu_gather provides everything that ARM needs:

 - range tracking
 - RCU table free
 - VM_EXEC tracking
 - VIPT cache flushing

The one notable curiosity is the 'funny' range tracking for classical
ARM in __pte_free_tlb().

No change in behavior intended.

	Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
	Acked-by: Will Deacon <will.deacon@arm.com>
	Cc: Andrew Morton <akpm@linux-foundation.org>
	Cc: Andy Lutomirski <luto@kernel.org>
	Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
	Cc: Borislav Petkov <bp@alien8.de>
	Cc: Dave Hansen <dave.hansen@linux.intel.com>
	Cc: H. Peter Anvin <hpa@zytor.com>
	Cc: Linus Torvalds <torvalds@linux-foundation.org>
	Cc: Nick Piggin <npiggin@gmail.com>
	Cc: Peter Zijlstra <peterz@infradead.org>
	Cc: Rik van Riel <riel@surriel.com>
	Cc: Russell King <linux@armlinux.org.uk>
	Cc: Thomas Gleixner <tglx@linutronix.de>
	Signed-off-by: Ingo Molnar <mingo@kernel.org>
(cherry picked from commit b78180b)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit ff2e6d7
upstream-diff |
  arch/arm64/Kconfig
        Context conflicts due to options HAVE_FUTEX_CMPXCHG,
        HAVE_FUNCTION_ARG_ACCESS_API not yet introduced into LTS 8.6.
  arch/x86/Kconfig
        Context conflicts due to the option HAVE_RCU_TABLE_INVALIDATE
        still being in LTS 8.6, but no longer in the upstream

Towards a more consistent naming scheme.

[akpm@linux-foundation.org: fix sparc64 Kconfig]
Link: http://lkml.kernel.org/r/20200116064531.483522-7-aneesh.kumar@linux.ibm.com
	Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
	Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
	Cc: Michael Ellerman <mpe@ellerman.id.au>
	Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
	Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
(cherry picked from commit 6adfe77d47bd5db38fd2e5b5786c77b86e462e13)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve-pre CVE-2025-38085
commit-author Peter Zijlstra <peterz@infradead.org>
commit 0d6e24d
upstream-diff |
  include/asm-generic/tlb.h
        Small conflict in the comments
  mm/mmu_gather.c
        - Context conflict in tlb_flush_mmu_free because
          580a586 ("asm-generic/tlb:
          rename HAVE_MMU_GATHER_NO_GATHER") wasn't backported and
          CONFIG_MMU_GATHER_NO_GATHER still has its old name
          CONFIG_HAVE_MMU_GATHER_NO_GATHER.
        - Context conflict in tlb_gather_mmu because
          3af4bd0 ("asm-generic/tlb:
          rename HAVE_MMU_GATHER_PAGE_SIZE") wasn't backported and
          CONFIG_MMU_GATHER_PAGE_SIZE still has its old name
          CONFIG_HAVE_MMU_GATHER_PAGE_SIZE.

As described in the comment, the correct order for freeing pages is:

 1) unhook page
 2) TLB invalidate page
 3) free page

This order equally applies to page directories.

Currently there are two correct options:

 - use tlb_remove_page(), when all page directores are full pages and
   there are no futher contraints placed by things like software
   walkers (HAVE_FAST_GUP).

 - use MMU_GATHER_RCU_TABLE_FREE and tlb_remove_table() when the
   architecture does not do IPI based TLB invalidate and has
   HAVE_FAST_GUP (or software TLB fill).

This however leaves architectures that don't have page based directories
but don't need RCU in a bind.  For those, provide MMU_GATHER_TABLE_FREE,
which provides the independent batching for directories without the
additional RCU freeing.

Link: http://lkml.kernel.org/r/20200116064531.483522-10-aneesh.kumar@linux.ibm.com
	Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
	Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
	Cc: Michael Ellerman <mpe@ellerman.id.au>
	Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
	Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
(cherry picked from commit d420cc00ee07b95443e2d9a0c6b4f4c1ee00bc36)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-71581
cve CVE-2025-38085
commit-author Jann Horn <jannh@google.com>
commit 1013af4
upstream-diff |
  - Context conflicts due to missing
    59d9094 ("mm: hugetlb: independent
    PMD page table shared count").
  - Exposed the `tlb_remove_table_sync_one' function for use in the
    solution (missing 2ba99c5
    ("mm/khugepaged: fix GUP-fast interaction by sending IPI")).

huge_pmd_unshare() drops a reference on a page table that may have
previously been shared across processes, potentially turning it into a
normal page table used in another process in which unrelated VMAs can
afterwards be installed.

If this happens in the middle of a concurrent gup_fast(), gup_fast() could
end up walking the page tables of another process.  While I don't see any
way in which that immediately leads to kernel memory corruption, it is
really weird and unexpected.

Fix it with an explicit broadcast IPI through tlb_remove_table_sync_one(),
just like we do in khugepaged when removing page tables for a THP
collapse.

Link: https://lkml.kernel.org/r/20250528-hugetlb-fixes-splitrace-v2-2-1329349bad1a@google.com
Link: https://lkml.kernel.org/r/20250527-hugetlb-fixes-splitrace-v1-2-f4136f5ec58a@google.com
Fixes: 39dde65 ("[PATCH] shared page table for hugetlb page")
	Signed-off-by: Jann Horn <jannh@google.com>
	Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
	Cc: Liam Howlett <liam.howlett@oracle.com>
	Cc: Muchun Song <muchun.song@linux.dev>
	Cc: Oscar Salvador <osalvador@suse.de>
	Cc: Vlastimil Babka <vbabka@suse.cz>
	Cc: <stable@vger.kernel.org>
	Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit d04a5a3a1d8e2f7b5d2e3fc2d5667d3198b19e45)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
@pvts-mat
pvts-mat marked this pull request as draft July 24, 2026 00:49
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