A 16-year-old bug in KVM's shadow MMU that lets a guest reach through the hypervisor and touch host kernel memory
KVM's shadow MMU reuses kvm_mmu_page structures when it thinks the guest is asking for a page-table it has already built. The reuse check compared the guest frame number (GFN) but not the full role. When a guest mutates a PDE so that a previously *direct=1* large-page shadow can be re-fetched with *direct=0* (a 4KB non-leaf mapping), the MMU hands back a stale, incompatible structure — a classic use-after-free of shadow-page state in the host kernel. The bug has lived in kvm_mmu_get_child_sp() since 2.6.36 (Aug 2010), affecting essentially every distro kernel between then and the July 2026 stable round (fix commit 81ccda30b4e8 plus siblings b1337aae5e19, 9291654d69e0, 2ad3afa40ac6, 5e470998a23e). Both Intel and AMD x86/x86_64 hosts are in scope; ARM64 KVM is not.
There is no NVD CVSS yet, so noisgate is establishing the first assessment. Reality: CRITICAL. Hyunwoo Kim (V4bel) has a working PoC published on GitHub that reliably panics the host, and the same researcher demonstrated the chain during Google's kvmCTF. He claims a private variant achieves full host code execution from an unprivileged guest kernel module. This is textbook hypervisor-escape territory — one bug, one guest, entire tenant plane.
5 steps from start to impact.
Land root inside a guest VM
januscape.ko from V4bel/Januscape), so the attacker must first hold root on the guest. In a multi-tenant cloud that's trivially the tenant themselves; in enterprise virt it means a compromised VM.- Attacker controls a guest VM
- Guest kernel accepts an unsigned/tenant-supplied module or attacker exploits an in-guest LPE first
- Locked-down guest images with signed-module enforcement raise the bar but don't stop a tenant with legitimate root
Reach a host that is using shadow paging
kvm_intel.ept=0, kvm_amd.npt=0), on very old CPUs without the extension, or — critically — inside nested virtualization where L1's shadow of L2 falls back to software MMU.- Host has
tdp_enabled=0OR nested virtualization is exposed to the guest - Guest has
+vmx/+svmCPU flags in the nested case
- EPT/NPT is default-on on virtually all post-2010 server hardware
- Most cloud providers disable nested virt by default; enabling it is opt-in per instance type (GCE nested-virt, Azure Dv3/Ev3 nested, EC2
.metal)
/sys/module/kvm_intel/parameters/ept and /sys/module/kvm_amd/parameters/npt; virsh capabilities shows nested support.Trigger the role mismatch in kvm_mmu_get_child_sp()
role.direct=1 (originally covering a 2MB large page) but where the new mapping requires direct=0 (a 4KB non-leaf). The GFN matches, so the reuse check passes; the role does not. KVM returns a stale kvm_mmu_page.- Ability to control guest page tables at 4KB and 2MB granularity
- Ability to force MMU walks that traverse both mapping sizes for the same GFN
- Requires precise scheduling of guest page-table writes; not a one-shot spray
kvm_mmu_get_child_sp / mmu_alloc_shadow_roots is the primary indicator.Convert UAF into host memory corruption
kvm_mmu_page, subsequent MMU operations dereference freed slab memory. The public PoC stops here and panics the host — sufficient for cross-tenant DoS. V4bel's private variant, per his statement, shapes the freed slab to hijack a function pointer and pivot to host-kernel code execution (ring-0 on the hypervisor).- Reliable slab feng-shui in
kvm_mmu_page_header_cache - Kernel without CFI or with a bypassable CFI configuration
- FG-KASLR, CONFIG_SLAB_FREELIST_HARDENED, CONFIG_RANDOM_KMALLOC_CACHES raise exploit complexity but do not neutralize
SLUB: kmalloc-* warnings), KFENCE hits.Own the hypervisor, pivot to sibling tenants
- Host executes attacker-controlled kernel code
- Provider-specific microVM sandboxes (Firecracker with jailer, Kata with seccomp) reduce reachable syscalls from the userspace vmm but do not blunt in-kernel KVM UAF
The supporting signals.
| In-the-wild | No confirmed ITW exploitation as of 2026-07-07; public PoC exists and was demonstrated at Google kvmCTF |
|---|---|
| Proof-of-concept | Public: V4bel/Januscape by *Hyunwoo Kim* — panics host. Author claims a private variant achieves host RCE |
| EPSS | 0.00176 (low percentile) — reflects lack of remote-network exposure, not exploit difficulty |
| KEV | Not listed |
| CVSS | No NVD/authority score. noisgate assessed 9.3 (CRITICAL) — vector approximates AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H with scope change to host |
| Affected | Linux kernel 2.6.36 → pre-2026-07 stable; Intel VMX and AMD SVM x86/x86_64. ARM64 KVM unaffected |
| Fixed | Upstream commit 81ccda30b4e8 plus siblings b1337aae5e19, 9291654d69e0, 2ad3afa40ac6, 5e470998a23e — merged into stable July 2026. Watch distro backports: RHEL, Ubuntu LTS, SUSE, Amazon Linux, Debian |
| Exposure gate | Requires shadow MMU code path — reached when tdp_enabled=0 OR nested virtualization is exposed to the guest. Modern EPT/NPT default-on hosts without nested = not reachable |
| CWE | CWE-416 Use-After-Free |
| Disclosed | 2026-07-04; researcher Hyunwoo Kim (V4bel) |
noisgate verdict.
The single decisive factor is the role multiplier: this bug lives inside a hypervisor's MMU and, when reached, terminates in guest-to-host escape — the canonical fleet-scale outcome for any KVM-based cloud, VDI farm, or private virt platform. A working public PoC and a kvmCTF-proven exploit chain mean the vendor's absent CVSS understates the operational reality.
Why this verdict
- Role multiplier — hypervisor: the affected component IS the isolation boundary. On any KVM host reaching the vulnerable path, chain outcome is guest→host ring-0 → cross-tenant memory read/write. That is the definitional CRITICAL outcome; nothing above it exists in the blast-radius spectrum.
- Public weaponization: V4bel's GitHub PoC panics hosts today, and the same researcher demonstrated it in Google's kvmCTF — one of the highest-signal exploit venues in the industry. Assume PoC-to-RCE gap collapses within weeks.
- Exposure gate narrows but does not eliminate: EPT/NPT-only hosts without nested virt are safe. But nested virt is turned on across Azure Dv3/Ev3, GCE nested-VM types, EC2
.metal, many on-prem OpenStack and Proxmox clusters running Windows-in-Windows or CI runners, and every kubevirt setup that does software-emulated nested. That is well above the 1% threshold — floor stays CRITICAL. - Friction adjustment (why not 10.0): attacker must already hold guest-root and the vulnerable shadow-MMU path must be reachable. That is enough to shave the score from a hypothetical unauth remote 10.0 down to 9.3, but not enough to reduce the bucket.
- Latent 16-year footprint: every unpatched long-term-support kernel is vulnerable, including embedded appliances, virtualization gateways, and older RHEL 7/8 hosts still in production.
Why not higher?
The chain requires attacker code execution inside a guest and requires the host to actually enter the shadow-MMU code path (nested virt exposed OR EPT/NPT disabled). Modern non-nested hosts with EPT/NPT on and default-secure never touch the vulnerable function. Those two prerequisites cap the score below a pristine 10.0.
Why not lower?
A HIGH would understate what happens when the chain lands. The affected component is a hypervisor MMU; the deployment-role floor for hypervisor-escape bugs with public PoCs and demonstrated exploitation is CRITICAL, and cloud/VDI installed-base share sits far above the 10% canonical threshold. Downgrading to HIGH would require evidence that <1% of KVM hosts ever reach the shadow-MMU path — no such evidence exists.
What to do — in priority order.
- Disable nested virtualization on every KVM host that does not require it — Nested virt is the primary path that forces the shadow MMU on modern hardware. On Intel:
modprobe kvm_intel nested=0; on AMD:modprobe kvm_amd nested=0; reboot guests. Deploy within 3 days per the noisgate CRITICAL mitigation SLA. - Verify EPT/NPT is enabled and forbid boot-time disables — Ensure
/sys/module/kvm_intel/parameters/eptand/sys/module/kvm_amd/parameters/nptreturnY. Remove anykvm_intel.ept=0orkvm_amd.npt=0from GRUB/cmdline. Config-manage via Ansible/Chef within 3 days. - Restrict guest-root privilege on multi-tenant hosts — For VDI and internal virt, block untrusted users from loading kernel modules inside their VM (signed-module enforcement,
kernel.modules_disabled=1after boot). Buys time until the kernel patch reaches every host. - Prioritize backport tracking for RHEL/Ubuntu/SUSE/Amazon Linux 2/AL2023 — Vendor backports of commits
81ccda30b4e8et al. will land staggered. Subscribe to distro USN/RHSA/SUSE-SU streams and gate live-patching (kpatch, kernel-live) as the first application layer within the 90-day noisgate remediation SLA. - Deploy KFENCE / KASAN sampling on canary hosts — Not prevention — early warning. A crash in
kvm_mmu_get_child_spon any host is a high-fidelity IoC for exploitation attempts.
- Guest-side EDR — the exploit runs after guest-root; guest telemetry never sees the host-kernel corruption.
- Host-based AV/EDR signatures — this is a UAF triggered by legitimate KVM ioctl sequences from qemu; there is no malicious syscall pattern to signature.
- Network segmentation / firewalls — the attack surface is the guest→host hypercall interface, not the network.
- Live migration to a 'patched' host — the guest itself is the attacker; migration does not sanitize it.
- SELinux/AppArmor confinement of qemu — the vulnerable code path is in the KVM kernel module, not qemu-userspace.
Crowdsourced verification payload.
Run on each KVM hypervisor host (not the guests). Requires root. Invoke as sudo ./check-cve-2026-53359.sh. It reports VULNERABLE if the kernel is pre-fix AND the shadow-MMU path is reachable, PATCHED if the kernel carries the fix, UNKNOWN otherwise.
#!/usr/bin/env bash
# noisgate: CVE-2026-53359 (Januscape) KVM shadow-MMU UAF checker
# Run on the HYPERVISOR host as root.
set -u
OUT_VULN=2
OUT_PATCH=0
OUT_UNK=3
log() { printf '[cve-2026-53359] %s\n' "$*" >&2; }
if [[ $EUID -ne 0 ]]; then
log 'must run as root'
exit $OUT_UNK
fi
# 1. Is this a KVM host at all?
if ! lsmod | grep -qE '^kvm(_intel|_amd)?\b'; then
log 'kvm module not loaded; host not affected in current state'
echo PATCHED
exit $OUT_PATCH
fi
KREL=$(uname -r)
log "kernel: $KREL"
# 2. Reachability gate: EPT/NPT on AND nested off => path not reachable
EPT=$(cat /sys/module/kvm_intel/parameters/ept 2>/dev/null || echo N)
NPT=$(cat /sys/module/kvm_amd/parameters/npt 2>/dev/null || echo N)
NEST_I=$(cat /sys/module/kvm_intel/parameters/nested 2>/dev/null || echo N)
NEST_A=$(cat /sys/module/kvm_amd/parameters/nested 2>/dev/null || echo N)
log "ept=$EPT npt=$NPT nested_intel=$NEST_I nested_amd=$NEST_A"
REACHABLE=0
[[ "$EPT" == "N" || "$EPT" == "0" ]] && REACHABLE=1
[[ "$NPT" == "N" || "$NPT" == "0" ]] && REACHABLE=1
[[ "$NEST_I" == "Y" || "$NEST_I" == "1" ]] && REACHABLE=1
[[ "$NEST_A" == "Y" || "$NEST_A" == "1" ]] && REACHABLE=1
# 3. Distro-aware fixed-version heuristic. Adjust as backports land.
# Upstream mainline fix in 6.10+ (stable July 2026).
check_upstream_fix() {
local ver=${KREL%%-*}
local major=${ver%%.*}; local rest=${ver#*.}; local minor=${rest%%.*}
if [[ $major -gt 6 ]] || { [[ $major -eq 6 ]] && [[ $minor -ge 10 ]]; }; then
return 0
fi
return 1
}
DISTRO_PATCHED=1
if command -v rpm >/dev/null 2>&1; then
# RHEL/CentOS: rely on changelog grep for the fix commit
if rpm -q --changelog kernel 2>/dev/null | grep -qiE '81ccda30b4e8|CVE-2026-53359'; then
DISTRO_PATCHED=0
else DISTRO_PATCHED=1; fi
elif command -v dpkg >/dev/null 2>&1; then
if dpkg -l 'linux-image-*' 2>/dev/null | grep -q "$KREL" && \
apt-get changelog "linux-image-$KREL" 2>/dev/null | grep -qiE 'CVE-2026-53359|81ccda30b4e8'; then
DISTRO_PATCHED=0
fi
fi
if check_upstream_fix || [[ $DISTRO_PATCHED -eq 0 ]]; then
echo PATCHED
exit $OUT_PATCH
fi
if [[ $REACHABLE -eq 1 ]]; then
echo VULNERABLE
exit $OUT_VULN
fi
log 'kernel appears unpatched but shadow-MMU path not reachable in current config'
echo UNKNOWN
exit $OUT_UNK
If you remember one thing.
kvm_intel.nested=0, kvm_amd.nested=0), verify EPT/NPT are enabled and pinned in GRUB, and run the verification script fleetwide to enumerate exposure. Within 90 days (noisgate remediation SLA): roll the vendor kernel carrying commit 81ccda30b4e8 and siblings to every hypervisor — RHEL, Ubuntu LTS, SUSE, Amazon Linux, Debian, and any custom-built kernels for appliances or embedded virt. Because a public PoC exists and Hyunwoo Kim claims an unreleased host-RCE variant, override standard change windows and treat cloud, VDI, and multi-tenant CI runners as tier-0 for accelerated live-patching (kpatch/kernel-live).Sources
- NVD CVE-2026-53359
- The Hacker News — 16-Year-Old Linux KVM Flaw
- Shield53 — Januscape technical brief
- SecurityOnline — Public PoC for Januscape KVM Escape
- V4bel/Januscape PoC repository
- Dark Web Informer — long-lived KVM bug resurfaces
- cvefeed.io — CVE-2026-53359 detail
- Mallory — Januscape guest-to-host escape
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.