CVE-2026-31466: mm/huge_memory: fix folio isn't locked in softleaf_to_folio()
In the Linux kernel, the following vulnerability has been resolved:
mm/hugememory: fix folio isn't locked in softleaftofolio()
On arm64 server, we found folio that get from migration entry isn't locked in softleaftofolio(). This issue triggers when mTHP splitting and zapnonpresentptes() races, and the root cause is lack of memory barrier in softleaftofolio(). The race is as follows:
CPU0 CPU1
deferredsplitscan() zapnonpresentptes() lock folio splitfolio() unmapfolio() change ptes to migration entries splitfoliotoorder() softleaftofolio() set flags(including PGlocked) for tail pages folio = pfnfolio(softleaftopfn(entry)) smpwmb() VMWARNONONCE(!foliotestlocked(folio)) prepcompoundpage() for tail pages
In splitfoliotoorder(), smpwmb() guarantees page flags of tail pages are visible before the tail page becomes non-compound. smpwmb() should be paired with smprmb() in softleaftofolio(), which is missed. As a result, if zapnonpresentptes() accesses migration entry that stores tail pfn, softleaftofolio() may see the updated compoundhead of tail page before page->flags.
This issue will trigger VMWARNONONCE() in pfnswapentryfolio() because of the race between folio split and zapnonpresentptes() leading to a folio incorrectly undergoing modification without a folio lock being held.
This is a BUGON() before commit 93976a20345b ("mm: eliminate further swapops predicates"), which in merged in v6.19-rc1.
To fix it, add missing smprmb() if the softleaf entry is migration entry in softleaftofolio() and softleaftopage().
[tujinjiang@huawei.com: update function name and comments]
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Patch 93976a20345b - Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Fixed in v6.19-rc1 - Configuration
In the Linux kernel code path for mTHP splitting, add the missing smp_rmb() in softleaf_to_folio() when the softleaf entry is a migration entry, paired with the existing smp_wmb() behavior in __split_folio_to_order(), to prevent VM_WARN_ON_ONCE(!folio_test_locked(folio) / folio lock state races.
Linux kernel mm/huge_memory (softleaf_to_folio / __split_folio_to_order) memory barrier pairing between softleaf and tail folio visibility = add missing smp_rmb() in softleaf_to_folio() for softleaf entries that are migration entries
Event History
Frequently Asked Questions
What conditions are required to trigger the issue?
The race requires mTHP splitting to occur concurrently with zap_nonpresent_ptes(). It involves zap_nonpresent_ptes() accessing a migration entry that stores a tail PFN while deferred splitting is changing the folio's compound-page state.
What is the observed impact when the race occurs?
The race can cause softleaf_to_folio() to return a folio that does not appear locked. This triggers VM_WARN_ON_ONCE() in pfn_swap_entry_folio().
Which systems are known to be exposed?
The issue was found on an arm64 server. The provided information identifies the affected software as the Linux kernel, but does not state whether other architectures are affected.
What is the underlying synchronization problem?
A write memory barrier in __split_folio_to_order() makes tail-page flags visible before the page becomes non-compound, but softleaf_to_folio() lacked the corresponding read memory barrier. It can therefore observe an updated compound_head before observing the updated page flags.