Linux Kernel mm/mseal VMA-Merge Stale-Bound Bug (CVE-2026-23416)
by Antonius / Blue Dragon Security (bluedragonsecurity) · 2026-07-05
- Severity
- Medium
- CVE
- CVE-2026-23416
- Category
- binary
- Affected product
- Linux kernel, mm/mseal.c / mm/vma.c (mseal_apply() / vma_merge_existing_range())
- Affected versions
- Linux 6.17 through 7.0-rc5; fixed in 7.0-rc6, and stable backports 6.18.21 / 6.19.11
- Disclosed
- 2026-07-05
- Patch status
- patched
Tags
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-05 |
| Author / Researcher | Antonius / Blue Dragon Security (bluedragonsecurity) |
| CVE / Advisory | CVE-2026-23416 |
| Category | binary |
| Severity | Medium |
| CVSS Score | Not specified in source |
| Status | PoC |
| Tags | linux-kernel, mseal, mm-subsystem, vma, logic-error, unprivileged, security-feature-bypass, memfd |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Linux kernel, mm/mseal.c / mm/vma.c (mseal_apply() / vma_merge_existing_range()) |
| Versions Affected | Linux 6.17 through 7.0-rc5; fixed in 7.0-rc6, and stable backports 6.18.21 / 6.19.11 |
| Language / Platform | C, standard Linux syscalls (memfd_create, mmap, mseal) |
| Authentication Required | No (unprivileged UID, no capabilities) |
| Network Access Required | No (local only) |
Summary
CVE-2026-23416 is a logic bug in the kernel’s mseal(2) implementation. mseal_apply() iterates over the target VMAs and advances its cursor by copying a previously-captured vm_end value, but the underlying vma_modify_flags() call can merge adjacent VMAs mid-iteration, changing vm_end out from under the stale copy. The next loop iteration then starts from an incorrect address, producing an inconsistent VMA range. On debug kernels this trips a VM_WARN_ON_VMG() assertion; on production kernels the inconsistency proceeds silently, meaning the VM_SEALED protection that mseal() is meant to guarantee can be applied to the wrong address range without any indication of failure. The included C PoC deterministically reproduces this by creating two adjacent memfd-backed mappings, partially sealing one, then issuing a second mseal() call that spans across the sealed/unsealed boundary and forces the vulnerable merge path.
Vulnerability Details
Root Cause
In mseal_apply(), curr_end = vma->vm_end is captured before a merge can occur; when vma_modify_flags() subsequently merges VMAs, the stale value is reused as curr_start on the next iteration instead of being refreshed from the (now different) VMA boundaries.
Attack Vector
- An unprivileged process creates two adjacent
memfd-backedmmap()regions (MAP_SHARED | MAP_FIXED). - It calls
mseal(2)on a sub-range of the first mapping, marking that VMAVM_SEALED. - It calls
mseal(2)again with a range that starts inside the now-sealed VMA and extends into the adjacent unsealed VMA, forcingvma_merge_existing_range()to merge them mid-iteration. - The stale
curr_start/curr_endbookkeeping produces an inconsistentvmgstate, trippingVM_WARN_ON_VMGon debug kernels (silent on production kernels).
Impact
On CONFIG_DEBUG_VM kernels, repeated kernel WARNINGs are logged (triggerable at will by an unprivileged user). More significantly, on production kernels the miscalculated range means mseal()’s sealing guarantee can be silently misapplied, undermining a security hardening primitive without any visible failure.
Environment / Lab Setup
Target: Linux kernel 6.17 - 7.0-rc5, ideally built with CONFIG_DEBUG_VM=y to observe the WARNING
Attacker: gcc, any unprivileged shell account (no root/capabilities needed)
Proof of Concept
PoC Script
See
cve-2026-23416-poc.cin this folder. A short write-up is also included asCVE-2026-23416-writeup.pdf, anddesc.mdhas the author’s update notes with a confirmed real-hardwaredmesgtrace.
| |
The program repeatedly forks, and in each child creates the two memfd mappings and issues the two mseal() calls described above, then periodically greps dmesg for the vma_merge_existing_range warning count so the operator can see it firing.
Detection & Indicators of Compromise
WARNING: CPU: X PID: Y at mm/vma.c:830 vma_merge_existing_range+0x...
Signs of compromise:
- Repeated
WARNING ... vma_merge_existing_rangeentries indmesg/kernel log, especially many originating from the same unprivileged UID/process in rapid succession. - Processes making tight loops of
memfd_create+mmap+msealsyscalls.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade to Linux 7.0-rc6 / 6.18.21 / 6.19.11 or later (fix commits 40b3f4700e55, 83737e34b83a, 2697dd8ae721). |
| Interim mitigation | No practical workaround short of patching; monitor dmesg for the vma.c:830 WARNING signature as an indicator of attempted triggering. |
References
Notes
Mirrored from https://github.com/bluedragonsecurity/CVE-2026-23416-POC on 2026-07-05.
| |