CVE-2026-52969 Overview
CVE-2026-52969 is a Linux kernel vulnerability in the Kernel-based Virtual Machine (KVM) subsystem. The flaw resides in kvm_reset_dirty_gfn(), where an unchecked u64 addition allows a wrapped offset to bypass the bounds check against memslot->npages. A local attacker holding /dev/kvm can craft dirty ring entries that produce a near-U64_MAX guest frame number, leading to an out-of-bounds read in gfn_to_rmap() and a conditional clear of PT_WRITABLE_MASK at an attacker-influenced location. The vulnerability was resolved upstream across multiple stable kernel branches.
Critical Impact
Any local process with access to /dev/kvm can trigger an out-of-bounds memory access in the kernel KVM shadow MMU path, enabling potential memory corruption and privilege escalation on hosts that run virtual machines.
Affected Products
- Linux kernel (multiple stable branches receiving the upstream fix)
- Hosts running KVM with shadow paging or write-tracked memory slots
- Any system exposing /dev/kvm to unprivileged users or container workloads
Discovery Timeline
- 2026-06-24 - CVE-2026-52969 published to NVD
- 2026-06-24 - Last updated in NVD database
Technical Details for CVE-2026-52969
Vulnerability Analysis
The defect is an integer overflow in the KVM dirty ring reset path. kvm_reset_dirty_gfn() validates a guest frame number range using if (!memslot || (offset + __fls(mask)) >= memslot->npages) return;. Because offset is a u64 and the addition is unchecked, a u64 wrap silently bypasses the guard.
The dirty ring backing these entries is mapped MAP_SHARED at KVM_DIRTY_LOG_PAGE_OFFSET of the vCPU file descriptor. The Virtual Machine Monitor (VMM) can therefore rewrite the slot and offset fields of any entry between when the kernel pushes them and when KVM_RESET_DIRTY_RINGS consumes them. Only the flags handshake is treated as the handover; the slot/offset payload is taken on trust.
With two crafted entries where entry[i].offset = 0xffffffffffffffc1 and entry[i+1].offset = 0, the coalescing loop in kvm_dirty_ring_reset() computes delta = 63, which falls in [0, BITS_PER_LONG) and folds the second entry into the existing mask by setting bit 63. The subsequent kvm_reset_dirty_gfn() call then sees offset = 0xffffffffffffffc1 and __fls(mask) = 63. Their sum wraps to zero, and the bounds check passes.
Root Cause
The root cause is improper input validation [CWE-190] combined with a missing range check on attacker-controlled u64 arithmetic. The kernel assumes the dirty ring payload remains consistent, but the shared mapping permits the VMM to mutate slot and offset after kernel population. The fix range-checks offset against memslot->npages independently before any addition, so the subsequent offset + __fls(mask) cannot overflow.
Attack Vector
The wrapped offset propagates into kvm_arch_mmu_enable_log_dirty_pt_masked() unchanged. On the legacy MMU path, when kvm_memslots_have_rmaps() returns true, such as on shadow paging, any virtual machine that has allocated shadow roots, or a write-tracked slot, the code reaches gfn_to_rmap(). That function indexes slot->arch.rmap[0][] with a near-U64_MAX gfn, producing an out-of-bounds load of a kvm_rmap_head, followed by a conditional clear of PT_WRITABLE_MASK at the loaded pointer. The path is reachable from any process holding /dev/kvm.
Detection Methods for CVE-2026-52969
Indicators of Compromise
- Unexpected kernel oops, soft lockups, or page faults originating in gfn_to_rmap or kvm_reset_dirty_gfn stack traces
- Local processes opening /dev/kvm and issuing KVM_RESET_DIRTY_RINGS with anomalously large offset values
- Sudden loss of write protection on guest pages or unexplained guest VM instability on a multi-tenant host
Detection Strategies
- Audit kernel versions against the upstream fix commits (01b71b9, 0d419c2, 0eb281e, 577a8d3, 74f1a22, b315b03, ecf9b3e) on stable trees
- Monitor dmesg and journalctl for KVM-related warnings, BUG_ON, or KASAN reports referencing rmap or dirty ring functions
- Track userspace processes that hold /dev/kvm and correlate with ioctl activity using auditd rules
Monitoring Recommendations
- Enable auditd rules on /dev/kvm open and ioctl calls to baseline expected hypervisor processes
- Forward kernel ring buffer logs to a central SIEM and alert on KVM subsystem panics or oopses
- Inventory hosts running shadow paging or write-tracked guests, since these expose the vulnerable code path
How to Mitigate CVE-2026-52969
Immediate Actions Required
- Apply the upstream Linux kernel patches from the linked stable commits to all KVM hosts
- Restrict access to /dev/kvm to trusted users and service accounts using group ownership and ACLs
- Identify and reboot hypervisor hosts after kernel package updates so the patched code is loaded
- Review container and multi-tenant configurations that expose /dev/kvm to untrusted workloads
Patch Information
The fix range-checks offset against memslot->npages on its own first, so the addition cannot wrap. Because memslot->npages is bounded well below U64_MAX, once offset < npages holds, offset + __fls(mask) with __fls(mask) < BITS_PER_LONG stays in range. The patch landed in multiple stable branches via commits 01b71b9, 0d419c2, 0eb281e, 577a8d3, 74f1a22, b315b03, and ecf9b3e.
Workarounds
- Disable shadow paging where feasible and ensure hardware-assisted nested paging (EPT/NPT) is used so the vulnerable legacy MMU path is not entered
- Avoid granting /dev/kvm access to untrusted users, containers, or nested virtualization tenants until the patch is applied
- Disable the dirty ring feature in the VMM configuration where supported, falling back to the legacy dirty bitmap interface
# Verify kernel version and restrict /dev/kvm access
uname -r
ls -l /dev/kvm
sudo chgrp kvm /dev/kvm
sudo chmod 0660 /dev/kvm
# Confirm only trusted accounts are in the kvm group
getent group kvm
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

