CVE-2025-39992
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
15/10/2025
Last modified:
16/10/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
mm: swap: check for stable address space before operating on the VMA<br />
<br />
It is possible to hit a zero entry while traversing the vmas in unuse_mm()<br />
called from swapoff path and accessing it causes the OOPS:<br />
<br />
Unable to handle kernel NULL pointer dereference at virtual address<br />
0000000000000446--> Loading the memory from offset 0x40 on the<br />
XA_ZERO_ENTRY as address.<br />
Mem abort info:<br />
ESR = 0x0000000096000005<br />
EC = 0x25: DABT (current EL), IL = 32 bits<br />
SET = 0, FnV = 0<br />
EA = 0, S1PTW = 0<br />
FSC = 0x05: level 1 translation fault<br />
<br />
The issue is manifested from the below race between the fork() on a<br />
process and swapoff:<br />
fork(dup_mmap()) swapoff(unuse_mm)<br />
--------------- -----------------<br />
1) Identical mtree is built using<br />
__mt_dup().<br />
<br />
2) copy_pte_range()--><br />
copy_nonpresent_pte():<br />
The dst mm is added into the<br />
mmlist to be visible to the<br />
swapoff operation.<br />
<br />
3) Fatal signal is sent to the parent<br />
process(which is the current during the<br />
fork) thus skip the duplication of the<br />
vmas and mark the vma range with<br />
XA_ZERO_ENTRY as a marker for this process<br />
that helps during exit_mmap().<br />
<br />
4) swapoff is tried on the<br />
&#39;mm&#39; added to the &#39;mmlist&#39; as<br />
part of the 2.<br />
<br />
5) unuse_mm(), that iterates<br />
through the vma&#39;s of this &#39;mm&#39;<br />
will hit the non-NULL zero entry<br />
and operating on this zero entry<br />
as a vma is resulting into the<br />
oops.<br />
<br />
The proper fix would be around not exposing this partially-valid tree to<br />
others when droping the mmap lock, which is being solved with [1]. A<br />
simpler solution would be checking for MMF_UNSTABLE, as it is set if<br />
mm_struct is not fully initialized in dup_mmap().<br />
<br />
Thanks to Liam/Lorenzo/David for all the suggestions in fixing this<br />
issue.