CVE-2026-23077
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
04/02/2026
Última modificación:
04/02/2026
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted merge<br />
<br />
Patch series "mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted<br />
merge", v2.<br />
<br />
Commit 879bca0a2c4f ("mm/vma: fix incorrectly disallowed anonymous VMA<br />
merges") introduced the ability to merge previously unavailable VMA merge<br />
scenarios.<br />
<br />
However, it is handling merges incorrectly when it comes to mremap() of a<br />
faulted VMA adjacent to an unfaulted VMA. The issues arise in three<br />
cases:<br />
<br />
1. Previous VMA unfaulted:<br />
<br />
copied -----|<br />
v<br />
|-----------|.............|<br />
| unfaulted |(faulted VMA)|<br />
|-----------|.............|<br />
prev<br />
<br />
2. Next VMA unfaulted:<br />
<br />
copied -----|<br />
v<br />
|.............|-----------|<br />
|(faulted VMA)| unfaulted |<br />
|.............|-----------|<br />
next<br />
<br />
3. Both adjacent VMAs unfaulted:<br />
<br />
copied -----|<br />
v<br />
|-----------|.............|-----------|<br />
| unfaulted |(faulted VMA)| unfaulted |<br />
|-----------|.............|-----------|<br />
prev next<br />
<br />
This series fixes each of these cases, and introduces self tests to assert<br />
that the issues are corrected.<br />
<br />
I also test a further case which was already handled, to assert that my<br />
changes continues to correctly handle it:<br />
<br />
4. prev unfaulted, next faulted:<br />
<br />
copied -----|<br />
v<br />
|-----------|.............|-----------|<br />
| unfaulted |(faulted VMA)| faulted |<br />
|-----------|.............|-----------|<br />
prev next<br />
<br />
This bug was discovered via a syzbot report, linked to in the first patch<br />
in the series, I confirmed that this series fixes the bug.<br />
<br />
I also discovered that we are failing to check that the faulted VMA was<br />
not forked when merging a copied VMA in cases 1-3 above, an issue this<br />
series also addresses.<br />
<br />
I also added self tests to assert that this is resolved (and confirmed<br />
that the tests failed prior to this).<br />
<br />
I also cleaned up vma_expand() as part of this work, renamed<br />
vma_had_uncowed_parents() to vma_is_fork_child() as the previous name was<br />
unduly confusing, and simplified the comments around this function.<br />
<br />
<br />
This patch (of 4):<br />
<br />
Commit 879bca0a2c4f ("mm/vma: fix incorrectly disallowed anonymous VMA<br />
merges") introduced the ability to merge previously unavailable VMA merge<br />
scenarios.<br />
<br />
The key piece of logic introduced was the ability to merge a faulted VMA<br />
immediately next to an unfaulted VMA, which relies upon dup_anon_vma() to<br />
correctly handle anon_vma state.<br />
<br />
In the case of the merge of an existing VMA (that is changing properties<br />
of a VMA and then merging if those properties are shared by adjacent<br />
VMAs), dup_anon_vma() is invoked correctly.<br />
<br />
However in the case of the merge of a new VMA, a corner case peculiar to<br />
mremap() was missed.<br />
<br />
The issue is that vma_expand() only performs dup_anon_vma() if the target<br />
(the VMA that will ultimately become the merged VMA): is not the next VMA,<br />
i.e. the one that appears after the range in which the new VMA is to be<br />
established.<br />
<br />
A key insight here is that in all other cases other than mremap(), a new<br />
VMA merge either expands an existing VMA, meaning that the target VMA will<br />
be that VMA, or would have anon_vma be NULL.<br />
<br />
Specifically:<br />
<br />
* __mmap_region() - no anon_vma in place, initial mapping.<br />
* do_brk_flags() - expanding an existing VMA.<br />
* vma_merge_extend() - expanding an existing VMA.<br />
* relocate_vma_down() - no anon_vma in place, initial mapping.<br />
<br />
In addition, we are in the unique situation of needing to duplicate<br />
anon_vma state from a VMA that is neither the previous or next VMA being<br />
merged with.<br />
<br />
dup_anon_vma() deals exclusively with the target=unfaulted, src=faulted<br />
case. This leaves four possibilities, in each case where the copied VMA<br />
is faulted:<br />
<br />
1. Previous VMA unfaulted:<br />
<br />
copied -----|<br />
<br />
---truncated---



