CVE-2026-98507

CVE-2026-98507

published October 18, 2026

CVSS
—
EPSS
0%
Percentile
9.3
In the wild
Unconfirmed
What it is

In the Linux kernel, the following vulnerability has been resolved:

mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish

On arm64 server, we find that a task trying to grab the anon_vma lock

triggers hungtask.

INFO: task main:2354726 blocked for more than 120 seconds.

Tainted: G E 5.10.0-0021.aarch64 #1

"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.

task:main state:D stack: 0 pid:2354726 ppid:2350673 flags:0x00000a01

Call trace:

__switch_to+0x7c/0xbc

__schedule+0x3b4/0x8a0

schedule+0x50/0xe0

rwsem_down_write_slowpath+0x3cc/0x6cc

down_write+0x60/0x260

__anon_vma_prepare+0x6c/0x210

do_anonymous_page+0x258/0x660

handle_pte_fault+0x188/0x214

__handle_mm_fault+0x1b0/0x380

handle_mm_fault+0xf4/0x284

do_page_fault+0x19c/0x494

do_translation_fault+0xcc/0xf8

do_mem_abort+0x48/0xac

el0_da+0x44/0x80

el0_sync_handler+0x88/0xb4

el0_sync+0x160/0x180

After analyzing the vmcore, we found the anon_vma->root->rwsem.count is

-1. There is another anon_vma whose anon_vma->root->rwsem.count is 1, the

anon_vma->root->rwsem.owner shows the lock is held, but the stack of the

task shows the task doesn't hold the anon_vma lock.

After adding more debugging info, we found __anon_vma_prepare() reuses

anon_vma and triggers the UAF of anon_vma->root due to missing memory

barrier, leading to locking and unlocking two different anon_vma->root,

thus leading to an anon_vma will never be unlocked, and another anon_vma

couldn't be locked anymore.

This race requires two adjacent VMAs that are not merged but are

anon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be

changed by mprotect()). Two threads fault on each VMA concurrently, both

calling __anon_vma_prepare() with only mmap_lock held for reading.

THREAD A THREAD B

__anon_vma_prepare __anon_vma_prepare

find_mergeable_anon_vma() -> NULL

anon_vma = anon_vma_alloc();

anon_vma->root = anon_vma;

// the two stores may be reordered

vma->anon_vma = anon_vma;

// finds A's anon_vma

anon_vma = find_mergeable_anon_vma(vma);

anon_vma_lock_write(anon_vma);

// may still see the old root

down_write(&anon_vma->root->rwsem);

anon_vma_unlock_write(anon_vma);

// see the new root, never unlock old

up_write(&anon_vma->root->rwsem);

thread A triggers page fault and calls __anon_vma_prepare() to prepare

anon_vma for the faulting vma. __anon_vma_prepare() allocates and

initializes a new anon_vma, and then publishes it to the vma with a plain

store. anon_vma_prepare() only requires the mmap_lock to be held for

reading, so two threads can fault on adjacent VMAs at the same time.

While thread A publishes a new anon_vma, thread B could find the anon_vma

via find_mergeable_anon_vma() and then locks anon_vma->root->rwsem.

The store to anon_vma->root in anon_vma_alloc() and the store to

vma->anon_vma can be reordered. The anon_vma_lock_write() and spin_lock()

only provide acquire semantics, which do not prevent prior stores from

being reordered after them. The release semantics of the corresponding

spin_unlock() and anon_vma_unlock_write() come too late, the store to

vma->anon_vma is already published before they take effect. As a result,

thread B can observe the following order:

vma->anon_vma = anon_vma;

anon_vma->root = anon_vma;

The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma

may reuse memory from a previously freed one. The constructor

(anon_vma_ctor) does not reset anon_vma->root, and __put_anon_vma()

doesn't clear it either, so the old root value persists until

anon_vma_alloc() overwrites it. If that store isn't v

---truncated---

The record
Technical detail
CVSS
Not scored
CVSS v4.0
Not supplied
EPSS
0.00200 · 9.3th percentile
Published
2026-10-18T20:17Z
References (5)
EPSS history
Timeline
  • 20 OCT 03:34Z
    EPSS moved — → 0%
    epss
  • 18 OCT 15:17Z
    mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
    cvelistv5
  • 18 OCT 15:17Z
    mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
    cvelistv5