CyberBytes Daily

Trending cyberattacks, explained simply.

critical vulnerability

How a 16-year-old one-line logic error lets a rented cloud VM crash or own its physical host

The entire premise of cloud computing is that your virtual machine cannot touch anyone else's. Your code runs in an isolated container, and the physical server underneath is invisible to you. A vulnerability disclosed on July 6, 2026, named Januscape, breaks that premise completely. A researcher with a single rented cloud VM can crash the physical host, taking every other tenant's machine offline at the same time. A second, unreleased exploit built on the same flaw would give that attacker full administrative control over the host and every VM running on it.

The flaw has been sitting in the Linux kernel since August 2010. For 16 years, every Linux server running KVM-based virtualization, which describes a significant share of public cloud infrastructure including Google Cloud and AWS, shipped with this defect. It was not hidden or obfuscated. It was simply old, complex, and only activated by a specific configuration that most security reviewers never tested. One researcher, Hyunwoo Kim, found it by looking where others had not.

The detail that should alarm anyone responsible for cloud infrastructure: the attack requires only root access inside a guest VM, which is the default condition when any user is allocated a cloud instance. You do not need to compromise anything. You just need to have rented a server.

Narrative · 6 min read

The Context

KVM, which stands for Kernel-based Virtual Machine, is the virtualization engine built into the Linux kernel. It lets a single physical server run dozens of isolated virtual machines simultaneously. When you rent a cloud instance from Google Cloud, AWS, or most other providers, there is a high probability that KVM is the software enforcing the boundary between your VM and every other tenant's VM on the same machine.

The security guarantee KVM provides is called isolation: your code cannot read, write, or interfere with memory belonging to another VM or to the host operating system. Januscape breaks that guarantee.

The Attack, Phase by Phase

Phase 1: The Hidden Flaw

KVM's shadow MMU tracks memory mappings using internal data structures called shadow pages. Each shadow page has two identifying attributes: a guest frame number (the address it maps) and a role (whether it represents a large 2MB block or a standard 4KB page).

A function called kvm_mmu_get_child_sp() decides whether to reuse an existing shadow page or create a new one. For 16 years, that function checked only the guest frame number. It never checked the role. A 2MB shadow page and a 4KB shadow page at the same address were treated as identical and interchangeable.

A separate fix shipped in May 2026 for a related bug (CVE-2026-46113) closed one path into this same code area, signaling to reviewers that the shadow MMU had been examined. It had not been fully examined. The role-mismatch path remained open, one field-check away from the same class of failure.

INSIDE KVM SHADOW MMU LOGIC📄1Shadow page created (2MB)Assigned guest frame number + role: direct=1🔍2Reuse check runskvm_mmu_get_child_sp() checks GFN only⚠️3Role mismatch ignored4KB mapping (direct=0) reuses 2MB page🗂️4Wrong rmap entry recordedBookkeeping now points to wrong GFNThe flaw existed in this form from August 2010 through June 2026.

Phase 2: The Trigger Condition

Modern cloud hosts use hardware-assisted memory translation (Intel EPT or AMD NPT) that bypasses the shadow MMU entirely under normal conditions. The shadow MMU only activates when nested virtualization is enabled.

An attacker with root access inside a rented cloud VM loads a malicious kernel module, then manipulates a guest memory table entry to create the role-mismatch condition. The entire attack happens through guest-side actions alone. No cooperation from the host's management software (QEMU) is required. The attack works identically on Intel and AMD hardware because the vulnerable code is shared between both architectures.

On Linux distributions such as Red Hat Enterprise Linux (RHEL), CentOS Stream, Rocky Linux, and AlmaLinux, the device file that controls KVM access (/dev/kvm) is world-readable by default. An unprivileged local user on the host, without running any VM, can also trigger the bug to crash the machine.

ATTACKER INSIDE A RENTED CLOUD VM☁️1Attacker rents cloud VMRoot access is default on most providers📦2Loads malicious kernel moduleNo QEMU or host cooperation needed🔧3Manipulates guest page tableCreates GFN match with role mismatch💾4KVM reuses wrong shadow pageStale rmap entry survives page freeGUEST/HOST BOUNDARYNested virtualization forces KVM into the legacy shadow MMU path even on modern hardware.

Phase 3: Two Outcomes, One Bug

The same memory corruption produces two different outcomes depending on how the attacker steers it.

The public proof-of-concept, released by Kim on July 6, 2026, steers the corruption into KVM's own internal consistency check. When KVM detects the mismatched bookkeeping entry, it panics the host kernel. The physical server crashes. Every VM on that machine goes offline simultaneously. A single malicious tenant can take down an entire physical host within seconds to minutes.

The second exploit, which Kim has stated he will not release, steers the same corruption to a controlled location in host kernel memory. Through memory shaping—carefully arranging what occupies freed memory before the corrupted pointer is followed—a constrained write can be escalated into full administrative code execution on the physical host, exposing every VM running on it.

TWO EXPLOIT PATHS FROM ONE MEMORY CORRUPTION💥1Memory corruption triggeredStale pointer dereferenced by host kernel🔴Path A: Host kernel panicAll co-tenant VMs crash immediately👑Path B: Full host root accessAll co-tenant VMs exposed to takeoverPath B exploit is withheld. Path A proof-of-concept is publicly available.

Phase 4: Patch and Mitigation

The fix is a one-line addition to kvm_mmu_get_child_sp(): the reuse check now compares both the guest frame number and the role field together. A shadow page is only reused when both attributes match.

Two patches are required together. Commit 81ccda30b4e8 addresses CVE-2026-53359 (the role-mismatch escape). Companion commit 0cb2af2ea66a addresses CVE-2026-46113 (the frame-number fix). CloudLinux confirmed that both are required: applying only one leaves the other path open. Fixed kernel versions shipped on July 4, 2026 across seven long-term support branches.

For hosts that cannot immediately apply the kernel update, disabling nested virtualization removes the attack surface entirely: set kvm_intel.nested=0 on Intel hosts or kvm_amd.nested=0 on AMD hosts.

REMEDIATION PATH🔍1Check kernel versionCompare against fixed stable releases📋2Verify both patches applied81ccda30b4e8 + 0cb2af2ea66a required🛡️3Apply kernel updateOr disable nested virt as interim stepApplying only one of the two patches leaves a structurally identical sibling path open.

What Made This Possible

  1. The shadow MMU was never audited under adversarial conditions. The code path only activates with nested virtualization enabled, a non-default configuration that most security reviewers never tested against.

  2. An incomplete fix created false confidence. The May 2026 fix for CVE-2026-46113 closed the guest-frame-number mismatch path in the same function, signaling that the code area had been reviewed. The role-mismatch path, structurally identical, remained open because reviewers stopped looking after the first fix landed.

  3. Default permissions on major Linux distributions expanded the blast radius. World-accessible /dev/kvm on RHEL and its derivatives meant the bug was exploitable by any unprivileged local user, not just cloud tenants with guest VMs.

What Should Have Stopped This

  • Disable nested virtualization on hosts that do not need it. Removing the configuration removes the attack surface before any code runs.
  • Restrict /dev/kvm permissions. World-accessible device files allowed unprivileged local users to reach the vulnerable code path without running a VM.
  • Apply both paired patches. Patch management processes that apply one without the other leave a sibling vulnerability open.
  • Treat legacy subsystems as unaudited until proven otherwise. Code that is old, complex, and only activated by specific configurations should receive adversarial review, not less of it.

The Takeaway

Januscape is not primarily a story about a single bug. It is a story about what happens when a foundational security boundary—the hypervisor isolation guarantee that all of multi-tenant cloud computing depends on—rests on a subsystem that has never been seriously stress-tested. The shadow MMU code was not hidden. It was simply old and complex enough that no one looked at it adversarially for 16 years.

The incomplete-fix dynamic compounds this. When CVE-2026-46113 was patched in May 2026, it created the impression that the shadow MMU had been reviewed and cleared. That impression was wrong. Incomplete fixes in complex subsystems do not reduce risk by half. They redirect attention away from the remaining risk entirely.

Pattern to remember: A partial fix in a complex subsystem signals clearance without providing it, making the remaining vulnerability harder to find than if no fix had shipped at all.

What changed: The hypervisor boundary, long treated as a hardware-enforced guarantee, is now understood to depend on the correctness of legacy software subsystems that have never received adversarial scrutiny.

Technical Deep Dive · 4 min

The Technical Mechanism

Januscape is a use-after-free vulnerability in kvm_mmu_get_child_sp(), located in arch/x86/kvm/mmu/mmu.c. The function is responsible for fetching or allocating struct kvm_mmu_page entries, the kernel structures KVM uses to track shadow page tables during nested virtualization.

Each kvm_mmu_page is identified by two fields: sp->gfn (the guest frame number it maps) and sp->role (a bitfield encoding page attributes including direct, which distinguishes large 2MB direct-mapped pages from standard 4KB shadowed page-table levels). The vulnerable reuse check compared only sp->gfn, ignoring sp->role.word entirely.

Exploitation path:

  1. An attacker inside a guest manipulates a page-directory entry (PDE) to point to a non-leaf page at a guest frame number that already has an existing shadow page with direct=1 (a 2MB large page mapping).
  2. kvm_mmu_get_child_sp() finds the existing shadow page by GFN match and incorrectly reuses it, even though the new mapping requires direct=0.
  3. KVM installs a leaf 4KB SPTE on the new path and records an rmap entry under the wrong GFN.
  4. When the child shadow page is later zapped, kvm_mmu_page_get_gfn() computes the wrong GFN using sp->gfn + index rather than sp->shadowed_translation[], fails to remove the rmap entry, and frees the shadow page.
  5. The stale rmap entry survives. Subsequent kernel operations that walk that GFN (dirty logging, MMU notifier invalidation) dereference a pointer into freed memory.
  6. The public proof-of-concept steers this dereference into pte_list_remove(), which fires KVM's internal consistency assertion and immediately panics the host.

The fix adds a single condition to the reuse check: sp->role.word == role.word must be true alongside the GFN match before a shadow page is reused. Both commit 81ccda30b4e8 (CVE-2026-53359) and companion commit 0cb2af2ea66a (CVE-2026-46113) are required. Applying only one leaves a structurally identical sibling path reachable.

The exploit module carries separate code paths for Intel (vmxon/vmlaunch) and AMD (vmrun) to trigger nested virtualization entry, but the underlying memory corruption is identical on both architectures because the vulnerable logic is in shared x86 KVM MMU code. ARM64 KVM is not affected.

On RHEL, CentOS Stream, Rocky Linux, AlmaLinux, and Oracle Linux EL8 and later, /dev/kvm ships with 0666 permissions (world-readable and writable). This allows any unprivileged local user to open the KVM device and trigger the bug for local privilege escalation to root without running a guest VM.

KVM_MMU_GET_CHILD_SP() ROLE-MISMATCH PATH📄1Existing shadow page (direct=1)GFN 0x1000, role.direct=1 in hash table🔍2GFN-only reuse check passesrole.word comparison absent pre-patch3Wrong page reused (direct=0 needed)SPTE installed, rmap recorded at wrong GFN🗑️4Shadow page freedrmap entry survives; stale pointer live💥5Use-after-free triggeredpte_list_remove() walks stale pointerThe fix: add role.word == role.word to the reuse condition in kvm_mmu_get_child_sp().

CVE and Advisories

  • CVE-2026-53359: KVM x86 shadow paging use-after-free due to unexpected role in kvm_mmu_get_child_sp(). Fixed by commit 81ccda30b4e8, merged mainline June 19, 2026. Stable kernels patched July 4, 2026: 7.1.3, 6.18.38, 6.12.95, 6.6.144, 6.1.177, 5.15.211, 5.10.260. NVD CVSS score not yet assigned as of July 7, 2026.
  • CVE-2026-46113: Related KVM shadow MMU use-after-free (rmap GFN mismatch). Fixed by companion commit 0cb2af2ea66a, May 2026. Both patches required together per CloudLinux advisory.
  • No CISA Known Exploited Vulnerabilities (KEV) entry or government advisory issued as of July 7, 2026.

MITRE ATT&CK Mapping

Technique IDATT&CK nameHow it appeared
T1611Escape to HostCore technique: guest VM escapes hypervisor isolation to execute code on the physical host via KVM shadow MMU use-after-free.
T1068Exploitation for Privilege EscalationOn RHEL-family hosts with world-accessible /dev/kvm, unprivileged local users exploit CVE-2026-53359 to escalate to root without a guest VM.
T1499Endpoint Denial of ServicePublic proof-of-concept steers memory corruption into pte_list_remove() assertion, crashing the host kernel and taking all co-tenant VMs offline.
T1059.004Unix Shell (via kernel module)Exploit is delivered as a loadable kernel module inside the guest, executing arbitrary kernel code in the context of the guest OS.

Indicators of Compromise

Detection is difficult. The exploit runs entirely as a kernel module inside a guest VM. From the host's perspective, the first observable event is typically the kernel panic itself, at which point the damage is done.

Host-Side Indicators

  • Unexpected kernel panic with stack trace referencing pte_list_remove, kvm_mmu_page_get_gfn, or kvm_mmu_get_child_sp in the crash dump.
  • Kernel oops or BUG messages in /var/log/kern.log or dmesg referencing KVM MMU consistency checks.
  • Sudden simultaneous termination of all guest VMs on a physical host without administrative action.

Guest-Side Indicators

  • Loading of an unsigned or unexpected kernel module (detectable via lsmod or auditd module-load events) immediately before a host crash.
  • Use of vmxon, vmlaunch (Intel), or vmrun (AMD) instructions from a non-hypervisor process, detectable via hardware performance counters or VM-exit logging if the host has such instrumentation.

No network indicators are associated with this vulnerability. The attack is entirely local to the physical host.

Attribution

Januscape was discovered by independent security researcher Hyunwoo Kim (@v4bel, imv4bel@gmail.com). Kim submitted the vulnerability as a zero-day through Google's kvmCTF vulnerability reward program, which offers up to $250,000 for full VM escape submissions, before coordinating responsible disclosure with the Linux kernel security team under embargo with linux-distros beginning June 12, 2026.

Kim is not affiliated with any threat actor group. No nation-state exploitation has been reported. No threat intelligence firm has attributed active exploitation to any actor as of July 7, 2026.

Januscape is Kim's third Linux kernel exploit disclosure in approximately two months, following Dirty Frag (CVE-2026-43284 / CVE-2026-43500, May 2026) and ITScape (June 2026). Kim noted that an attacker without guest root access could chain Dirty Frag with Januscape to achieve full host compromise from an unprivileged starting position.


Primary Sources