CVE-2026-74632
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
22/08/2026
Last modified:
23/08/2026
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
mm/huge_memory: fix huge_zero_pfn race<br />
<br />
Patch series "mm/huge_memory: fix huge_zero_pfn race", v2.<br />
<br />
There is a subtle race in the reference-counted huge_zero_folio<br />
implementation.<br />
<br />
The fast path atomic logic fails to account for the fact that the shrinker<br />
(which drops the final huge_zero_refcount pin) can overwrite huge_zero_pfn<br />
with the ~0UL sentinel value in shrink_huge_zero_folio_scan() after a<br />
racing get_huge_zero_folio() installed a valid value there.<br />
<br />
This results in huge_zero_folio being correctly set but huge_zero_pfn<br />
being set incorrectly and thus is_huge_zero_pfn() and consequently<br />
is_huge_zero_pmd() will misidentify the huge zero folio as being an<br />
ordinary THP folio.<br />
<br />
This can result in the huge zero folio being split and otherwise treated<br />
incorrectly.<br />
<br />
The solution to this is very subtle as there is an atomic fast path, and<br />
thus ordering in weakly ordered architectures has to be treated very<br />
carefully.<br />
<br />
The first commit fixes the issue by introducing a spinlock around<br />
huge_zero_[pfn, folio, refcount] write, with careful consideration paid to<br />
load/store ordering in the fast path. It is placed first and kept as<br />
small as possible so that it can be backported on its own.<br />
<br />
The second commit is a pure cleanup which reworks the<br />
CONFIG_PERSISTENT_HUGE_ZERO_FOLIO logic to better separate the persistent<br />
logic from the dynamically allocated one.<br />
<br />
<br />
This patch (of 2):<br />
<br />
If !CONFIG_PERSISTENT_HUGE_ZERO_FOLIO, the huge_zero_folio is refcounted<br />
by huge_zero_refcount and returned by mm_get_huge_zero_folio().<br />
<br />
When the caller is done with the huge zero page, its reference count is<br />
decremented. Only a shrinker can set the reference count to zero.<br />
<br />
A race can unfortunately occur between a shrinker decrementing the<br />
reference count to zero and a concurrent page fault.<br />
<br />
This is because shrink_huge_zero_folio_scan() might, if very unlucky, be<br />
preempted between setting huge_zero_refcount to zero and writing an<br />
invalid value.<br />
<br />
During this time get_huge_zero_folio() could write to huge_zero_pfn before<br />
shrink_huge_zero_folio_scan() resumes.<br />
<br />
In this event the huge zero folio will be persistently misidentified<br />
causing the THP code path to be entered inappropriately for the huge zero<br />
folio:<br />
<br />
CPU 0 CPU 1<br />
=======================================|=================================<br />
shrink_huge_zero_folio_scan() |<br />
atomic_cmpxchg() sets refcount to 0 |<br />
xchg() sets huge_zero_folio to NULL | get_huge_zero_folio()<br />
| | atomic_inc_not_zero() -> zero<br />
preempted for a long time | Allocate new huge zero folio<br />
| | Write valid huge_zero_folio<br />
v | Write valid huge_zero_pfn<br />
Overwrite huge_zero_pfn with ~0UL
Impact
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/105d04edbec83010df5728f74d17fd9c108e7553
- https://git.kernel.org/stable/c/33192a26cddea7a7e4ca66e5c3eebd36fa8be2bb
- https://git.kernel.org/stable/c/6024f6d0d9b9ca5138bfc4ac6f6e4bdf616e42b3
- https://git.kernel.org/stable/c/9332b080ad57650d1dc582e54517f9fc78ef89cc
- https://git.kernel.org/stable/c/ab7e4b407c7f58d1a003134eff3841f303d5ccc2
- https://git.kernel.org/stable/c/f3a874a903053c53fb53ba287ea9eacda69c68e8


