# Red Alert for Virtualization Infrastructure: Januscape Vulnerability Allows Attackers to Hijack Host Rights from Guest VM.

## Risk Summary

CVE-2026-53359, dubbed Januscape, is a use-after-free vulnerability in the shadow MMU subsystem of Linux KVM/x86. The vulnerability allows a virtual machine (guest) to perform two actions that have different levels of impact on the physical server (host): causing the entire host kernel to crash (and taking with it every other VM on the same physical machine), or — according to research that has not been fully published — executing arbitrary code with root privileges on the host.

The bug has existed since August 2010 and has affected every x86 Linux kernel running KVM with nested virtualization since then — about 16 years. ARM64 is not affected. The vulnerability requires the attacker to have root privileges within the guest VM — a common condition in any rented cloud instance.

This is a serious problem for x86 cloud service providers (including domestic private cloud systems), especially when nested virtualization is enabled to serve customers who need to run nested VMs.

## Technical Background

<table style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Criteria</strong></p></td><td colspan="1" rowspan="1"><p><strong>Details (Januscape Vulnerability)</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>CVE</strong></p></td><td colspan="1" rowspan="1"><p>CVE-2026-53359</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Product</strong></p></td><td colspan="1" rowspan="1"><p><strong>KVM (Kernel-based Virtual Machine)</strong> virtualization module in the Linux kernel (exists since August 2010, supports both Intel and AMD CPUs).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>CWE</strong></p></td><td colspan="1" rowspan="1"><p><strong>CWE-416</strong> (Use-After-Free).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>CVSS 3.1</strong></p></td><td colspan="1" rowspan="1"><p>Severity: <strong>Critical/High</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Prerequisites</strong></p></td><td colspan="1" rowspan="1"><p>1. The physical server (Host) allows/enables <strong>Nested Virtualization</strong>.<br><br>2. The attacker must obtain the highest privileges (<code>root</code>) inside the guest virtual machine (Guest VM).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Exploitation</strong></p></td><td colspan="1" rowspan="1"><p><strong>Guest-to-Host Escape</strong>: Escape the virtual machine to execute arbitrary code (RCE) on the physical host with root privileges; Crash the entire host server (Host Kernel Panic / DoS); Local Privilege Escalation (LPE).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Discovered by</strong></p></td><td colspan="1" rowspan="1"><p>Security researcher <strong>Hyunwoo Kim</strong> (alias <strong>@v4bel</strong>).</p></td></tr></tbody></table>

## Scope of Influence

*   Vulnerable from: commit 2032a93d66fa — August 1, 2010 (Linux 2.6.36 era)
    
*   Fixed at: commit 81ccda30b4e8 — June 16, 2026 (merge mainline)
    
*   Affected architectures: Intel x86, AMD x86
    
*   Unaffected architecture: ARM64
    

Stable kernel versions have been patched (released July 4, 2026):

| **Stable branch** | Fixed version |
| --- | --- |
| v7.x | 7.1.3 |
| v6.18.x | 6.18.38 |
| v6.12.x | 6.12.95 |
| v6.6.x | 6.6.144 |
| v6.1.x | 6.1.177 |
| v5.15.x | 5.15.211 |
| v5.10.x | 5.10.260 |

Mining conditions:

*   The attacker has root privileges inside the guest VM (satisfactory on any common cloud instance).
    
*   Nested virtualization is enabled on the host (kvm\_intel.nested=1 or kvm\_amd.nested=1).
    
*   No cooperation is required from QEMU or any VMM userspace.
    
*   No interaction from other users is required.
    

Attack vector: Local (Guest) → Host Kernel — not remote over network.

## Introduction to Linux KVM/x86

To understand Januscape, we'll need to understand three technical layers: How KVM works, how KVM manages memory, and how nested virtualization changes things. Each layer is a necessary condition for a vulnerability to exist.

### What is KVM?

KVM (Kernel-based Virtual Machine) is a virtualization technology that has been integrated directly into the Linux kernel since 2007. Instead of running as a separate software, KVM turns Linux into a hypervisor — the kernel both operates the real machine and manages virtual machines running on it.

The actual architecture consists of two coordinated parts:

*   KVM (kernel module): handles guest CPU and memory — sensitive part, runs in kernel space
    
*   QEMU (userspace): emulates devices such as disk, network card — less privileged part
    

Januscape resides entirely within the KVM kernel. QEMU is not involved.

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/617f6c7d-cd26-462b-bb27-ede1f3022477.png align="center")

### Memory Issues — Why Not Simple?

The Guest VM thinks it owns all of the RAM from address 0. In fact, that "RAM" is just a region of the host's memory that KVM allocates. KVM must continuously translate: the address used by the guest → the actual physical address on the hardware.

```plaintext
Guest address (GPA) → [KVM translation] → Real physical address (HPA)
```

Modern CPUs (Intel since 2008, AMD since 2008) have hardware that does this automatically — called EPT (Intel) or NPT (AMD). KVM uses EPT/NPT by default and works well.

Shadow paging is an older solution, handled by the KVM software itself instead of the hardware. It's slower and more complex — but still in the codebase and still triggered in a critical situation.

### Nested Virtualization — Januscape trigger conditions

Nested virtualization is the ability to run a hypervisor inside a VM. Real-life example: you rent a VM on AWS, then run VMware ESXi or KVM inside that VM to create additional child VMs.

Physical machine → Host KVM (L0)

└→ Your VM (L1) — guest has nested virt

└→ Child VM inside VM (L2)

This feature is very popular in the cloud: Kubernetes with VM worker nodes, hypervisor test environments, or cloud-in-cloud.

Here's the problem: when the L1 guest runs the hypervisor and needs to manage memory for its L2 guest, the KVM host can no longer use simple EPT/NPT — it must re-enable shadow paging to handle memory for this nested layer.

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Configuration</strong></p></td><td colspan="1" rowspan="1"><p><strong>Memory mechanism</strong></p></td><td colspan="1" rowspan="1"><p><strong>Can Januscape exploit it?</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p>Regular KVM (non-nested)</p></td><td colspan="1" rowspan="1"><p>EPT/NPT (hardware)</p></td><td colspan="1" rowspan="1"><p>No</p></td></tr><tr><td colspan="1" rowspan="1"><p>KVM with nested virtualization enabled</p></td><td colspan="1" rowspan="1"><p>Shadow paging (software)</p></td><td colspan="1" rowspan="1"><p>Yes</p></td></tr></tbody></table>

Shadow paging has been around for 16 years with a small flaw in the way it identifies and reuses "shadow pages" — which is exactly what Januscape exploited.

## Mining Mechanism

### **Root Cause**

KVM/x86 implements shadow paging — a mechanism that maintains a separate page table (shadow page table) to map the guest's virtual address to the host's physical address, used when EPT/NPT hardware is not working or when nested virtualization forces KVM to go through legacy code paths.

Each shadow page is characterized by two attributes:

*   GFN (Guest Frame Number): guest memory address that the shadow page manages
    
*   Role: type of shadow page — including direct (direct mapping, used for large 2MB pages) and indirect (mapping via page directory, used for 4KB pages)
    

The function kvm\_mmu\_get\_child\_sp() is responsible for finding or creating a child shadow page. The flaw lies here: this function only compares GFN but ignores role.word when deciding to reuse an old shadow page.

### Specific exploitation situations

1.  Guest creates a PDE (Page Directory Entry) pointing to large 2MB page → KVM grants shadow page with direct=1
    
2.  Guest changes that PDE to point to non-leaf page (4KB) → KVM needs shadow page with direct=0
    
3.  kvm\_mmu\_get\_child\_sp() finds old shadow page with matching GFN, reuses it without checking role
    
4.  KVM installs leaf SPTE (4KB) on shadow page with direct=1 — record rmap entry according to GFN from sp->gfn + index instead of sp->shadowed\_translation\[\]
    
5.  When shadow page is deleted, rmap\_remove() calculates GFN incorrectly → cannot delete rmap entry → dangling pointer
    
6.  When the memslot is dropped, the shadow page is released but the rmap entry still exists
    
7.  Later code (dirty logging, MMU notifier invalidation...) dereference SPTE in freed page → use-after-free
    

### Two parallel impacts

Impact 1 — Host DoS (public PoC): In most cases, the kernel detects corruption and kills itself with a BUG/panic. This is what Kim's PoC exploits: a race condition running in the guest causes the host to panic after a few seconds to a few minutes.

`[*] poc step 4/4: race live -- host DoS triggering ...`

`kernel BUG at arch/x86/kvm/mmu/mmu.c (pte_list_remove)`

`Comm: qemu-kvm`

Impact 2 — Full Host RCE (exploit not yet public): In rarer cases, the freed page is re-allocated by the allocator for another purpose before the cleanup runs. Cleanup then writes a value to memory that no longer belongs to it — the attacker controls the write destination. From this limited "write-what-where" primitive, Kim claims to have successfully built full escape in a controlled environment. Exploit path details for Intel and AMD may differ in the final step.

### Use in kvmCTF

Januscape was used by Kim as a 0-day submission in Google kvmCTF — Google's controlled bug bounty program for KVM, with a maximum reward of $250,000 for full guest-to-host escape. This is proof that the complete exploit exists and has been verified in a controlled environment.

## PoC Analysis

Purpose of this section: Technical analysis of poc.c to understand how the vulnerability is triggered in practice — not intended as an attack guide. PoC only triggers DoS path (host kernel panic); full escape exploit was not released.

### Overview architecture

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/0244c90a-976b-4626-b324-491bba70fa18.png align="center")

PoC supports dual-arch — same codebase, two virtualization backends:

*   Intel (default): use VMX instruction set (vmxon, vmwrite, vmlaunch)
    
*   AMD (amd=1): use SVM/VMCB (vmrun, VMCB struct)
    

Both paths fall into the same error in the KVM shadow MMU host.

### Module parameters and their meaning

<table style="min-width: 100px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Variable Name</strong></p></td><td colspan="1" rowspan="1"><p><strong>Data Type</strong></p></td><td colspan="1" rowspan="1"><p><strong>Value</strong></p></td><td colspan="1" rowspan="1"><p><strong>Meaning / Description</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><code>amd</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>0</code></p></td><td colspan="1" rowspan="1"><p>Virtualization architecture routing: <code>0</code> for Intel VMX, <code>1</code> for AMD SVM.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>nvcpu</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>8</code></p></td><td colspan="1" rowspan="1"><p>Number of vCPU threads participating in the race condition process.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>dwell</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>256</code></p></td><td colspan="1" rowspan="1"><p>Sleep time (in microseconds - µs) of the WRITER thread in each loop iteration.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>run_ms</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>600000</code></p></td><td colspan="1" rowspan="1"><p>Maximum lifetime (timeout) of the entire PoC (600,000 ms = 10 minutes).</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>diag</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>1</code></p></td><td colspan="1" rowspan="1"><p>Flag to enable printing diagnostic error logs to the screen (1 = On).</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>nflood</code></p></td><td colspan="1" rowspan="1"><p><code>static int</code></p></td><td colspan="1" rowspan="1"><p><code>0</code></p></td><td colspan="1" rowspan="1"><p>Number of extra "flood" threads spawned to increase pressure (load) on the system.</p></td></tr></tbody></table>

nvcpu = 8 is the most important — the more vCPUs participating in the race, the higher the probability of hitting window timing. On multi-core machines, PoC usually panics the host within a few seconds to a few minutes.

### Step 1 — Setup nested VM with page table control

PoC allocates a set of physical pages and builds a complete set of page tables for L2 guests:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/69723128-105b-4373-a9fa-5dbd324570c4.png align="center")

The L2 page directory (PD) is carefully structured so that the initial GVA\_PRIME address points to a 2MB large page (PDE with bit PS=1). This is a condition for the KVM host to create a shadow page with direct=1 at that PDE slot.

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/29268f5f-2923-4f38-9a62-f391070b0954.png align="center")

Then the PoC for L2 runs and performs a page walk through the GVA\_PRIME address — the KVM host will fetch the shadow page for this PDE slot, creating kvm\_mmu\_page with role.direct=1, gfn=ptg\_pa>>12.

### Step 2 — Next\_grip() function: Logic toggle creates race condition

Here is the central function of the race condition:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/fa8e5c60-665d-4b68-84ea-6ff527c500d9.png align="center")

next\_grip() protocols the PDE toggling continuously between two states:

<table style="min-width: 100px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Call</strong></p></td><td colspan="1" rowspan="1"><p><strong>PDE Value</strong></p></td><td colspan="1" rowspan="1"><p><strong>Required shadow page</strong></p></td><td colspan="1" rowspan="1"><p><a target="_self" rel="noopener noreferrer nofollow" class="text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer" href="http://role.direct" style="pointer-events: none;"><strong>role.direct</strong></a></p></td></tr><tr><td colspan="1" rowspan="1"><p>Calls 1, 9, 17... (mod 8 = 0)</p></td><td colspan="1" rowspan="1"><p>Large 2MB (PS=1)</p></td><td colspan="1" rowspan="1"><p><code>direct=1</code></p></td><td colspan="1" rowspan="1"><p>1</p></td></tr><tr><td colspan="1" rowspan="1"><p>Calls 2–8, 10–16...</p></td><td colspan="1" rowspan="1"><p>Small 4KB table</p></td><td colspan="1" rowspan="1"><p><code>direct=0</code></p></td><td colspan="1" rowspan="1"><p>0</p></td></tr></tbody></table>

Goal: while WRITER thread is toggling PDE from large → small (needs direct=0), FAULT thread trigger page fault forces KVM host to run kvm\_mmu\_get\_child\_sp(). If the timing is correct, KVM finds an old shadow page with matching gfn (from the previous large page) but role.direct=1 — and due to a bug, it reuses the shadow page with the wrong role instead of creating a new one.

### Step 3 — WRITER thread and FAULT thread coordinate

PoC spawns two types of threads according to role:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/df3ebdd1-4be0-4c86-a954-269a961997b9.png align="center")

WRITER thread runs a tight loop:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/6c4bbd65-819e-4773-974f-0c55a7711b5c.png align="center")

FAULT thread trigger page fault at GVA\_PRIME in L2:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/0cf084ba-76fa-4f22-8091-ffaa39926409.png align="center")

The race window is the time between when WRITER records the new PDE (requires direct=0) and when the KVM host invalidates the old shadow page (direct=1). In this window, FAULT thread triggers fetch path — KVM sees GFN match, ignores role, reuses wrong shadow page.

### Step 4 — From role mismatch to kernel panic

After reuse occurs, the KVM host installs leaf SPTE (4KB) into the shadow page with direct=1. When calculating GFN to register to rmap:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/1b7a88c0-0d37-4f70-9b8f-90784361ae33.png align="center")

The Rmap entry is registered with the guest's actual GFN (correct). But when rmap remove, it calculates GFN by sp->gfn + index (wrong because this is a direct page). Two GFNs do not match → pte\_list\_remove() cannot find entry → triggers BUG\_ON:

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/9b1f0449-ae33-4844-970f-99757d7d9210.png align="center")

The host kernel kills itself using BUG() — this causes the entire VM on the same physical host to be shut down, because the host kernel is no longer active.

### Why do Intel and AMD both suffer — but the code is different?

The bug is in the KVM shadow MMU host — code shared by both Intel and AMD. The difference is only in the guest layer L1 hypervisor setup in PoC:

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p></p></td><td colspan="1" rowspan="1"><p><strong>Intel path</strong></p></td><td colspan="1" rowspan="1"><p><strong>AMD path (amd=1)</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Instruction set</strong></p></td><td colspan="1" rowspan="1"><p>VMX: <code>vmxon</code>, <code>vmwrite</code>, <code>vmlaunch</code></p></td><td colspan="1" rowspan="1"><p>SVM: <code>vmrun</code>, VMCB struct</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Nested EPT/NPT config</strong></p></td><td colspan="1" rowspan="1"><p>EPT Pointer register</p></td><td colspan="1" rowspan="1"><p>VMCB <code>nested_ctl</code> / <code>misc_ctl</code></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Code in PoC</strong></p></td><td colspan="1" rowspan="1"><p><code>intel_cpu_on()</code>, <code>intel_vcpu_run()</code></p></td><td colspan="1" rowspan="1"><p><code>svm_cpu_on()</code>, <code>svm_vcpu_run()</code></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Host KVM bug path</strong></p></td><td colspan="1" rowspan="1"><p>Same — <code>kvm_mmu_get_child_sp()</code></p></td><td colspan="1" rowspan="1"><p>Same</p></td></tr></tbody></table>

This explains why Januscape is the first KVM escape triggerable on both Intel and AMD — not because Kim wrote two separate exploits, but because the bug lies in the common abstraction layer above both.

## Record exploitation

Status: PoC public, full exploit not yet public, no in-the-wild exploitation recorded outside of kvmCTF.

**CISA SSVC assessment (07/07/2026):**

![](https://cdn.hashnode.com/uploads/covers/6777abffdb647396c7d71de4/28d26dd3-c3be-4505-893d-1492e09c0caa.png align="center")

technicalImpact: total reflects that if the full exploit is used successfully, the attacker takes full control of the host — including all other guest VMs on the same physical machine.

### Event timeline

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Milestone</strong></p></td><td colspan="1" rowspan="1"><p><strong>Date</strong></p></td><td colspan="1" rowspan="1"><p><strong>Details</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p>Bug introduced</p></td><td colspan="1" rowspan="1"><p>01/08/2010</p></td><td colspan="1" rowspan="1"><p>Commit <code>2032a93d66fa</code>, Linux 2.6.36</p></td></tr><tr><td colspan="1" rowspan="1"><p>Kim submitted kvmCTF</p></td><td colspan="1" rowspan="1"><p>Before 06/2026</p></td><td colspan="1" rowspan="1"><p>Used as 0-day, full escape</p></td></tr><tr><td colspan="1" rowspan="1"><p>Embargo started</p></td><td colspan="1" rowspan="1"><p>Before 06/2026</p></td><td colspan="1" rowspan="1"><p>Report sent to <a target="_self" rel="noopener noreferrer nofollow" class="text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer" href="mailto:linux-distros@vs.openwall.org" style="pointer-events: none;">linux-distros@vs.openwall.org</a></p></td></tr><tr><td colspan="1" rowspan="1"><p>Patch merged to mainline</p></td><td colspan="1" rowspan="1"><p>19/06/2026</p></td><td colspan="1" rowspan="1"><p>Commit <code>81ccda30b4e8</code> by Paolo Bonzini</p></td></tr><tr><td colspan="1" rowspan="1"><p>Embargo ended</p></td><td colspan="1" rowspan="1"><p>06/07/2026</p></td><td colspan="1" rowspan="1"><p>Disclosed on oss-security</p></td></tr><tr><td colspan="1" rowspan="1"><p>Stable kernels patched</p></td><td colspan="1" rowspan="1"><p>04/07/2026</p></td><td colspan="1" rowspan="1"><p>7 stable branches</p></td></tr><tr><td colspan="1" rowspan="1"><p>PoC public</p></td><td colspan="1" rowspan="1"><p>06/07/2026</p></td><td colspan="1" rowspan="1"><p>GitHub V4bel/Januscape</p></td></tr><tr><td colspan="1" rowspan="1"><p>Debian DSA-6381-1</p></td><td colspan="1" rowspan="1"><p>05/07/2026</p></td><td colspan="1" rowspan="1"><p>testing/trixie and unstable/sid</p></td></tr></tbody></table>

### Distribution patch status (at time of publication)

| **Branch** | Fixed version |
| --- | --- |
| v7.x | **7.1.3** |
| v6.18.x | **6.18.38** |
| v6.12.x | **6.12.95** |
| v6.6.x | **6.6.144** |
| v6.1.x | **6.1.177** |
| v5.15.x | **5.15.211** |
| v5.10.x | **5.10.260** |

## **MITRE ATT&CK Mapping**

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Tactic</strong></p></td><td colspan="1" rowspan="1"><p><strong>Technique</strong></p></td><td colspan="1" rowspan="1"><p><strong>Relevance</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p>Privilege Escalation</p></td><td colspan="1" rowspan="1"><p><strong>T1611</strong> – Escape to Host</p></td><td colspan="1" rowspan="1"><p>Core technique — escape from guest VM to host</p></td></tr><tr><td colspan="1" rowspan="1"><p>Privilege Escalation</p></td><td colspan="1" rowspan="1"><p><strong>T1068</strong> – Exploitation for Privilege Escalation</p></td><td colspan="1" rowspan="1"><p>Kernel UAF to escalate to root privileges</p></td></tr><tr><td colspan="1" rowspan="1"><p>Execution</p></td><td colspan="1" rowspan="1"><p><strong>T1059.004</strong> – Command and Scripting Interpreter: Unix Shell</p></td><td colspan="1" rowspan="1"><p>Execute after getting a shell on the host</p></td></tr><tr><td colspan="1" rowspan="1"><p>Impact</p></td><td colspan="1" rowspan="1"><p><strong>T1499.004</strong> – Endpoint Denial of Service: Application or System Exploitation</p></td><td colspan="1" rowspan="1"><p>DoS path — crash host kernel</p></td></tr><tr><td colspan="1" rowspan="1"><p>Defense Evasion</p></td><td colspan="1" rowspan="1"><p><strong>T1014</strong> – Rootkit</p></td><td colspan="1" rowspan="1"><p>Potential after getting host root, establish persistence</p></td></tr></tbody></table>

## Detection and Response

### Detection — Host side

**Monitor kernel panic signature:**

*   If the host is attacked via a DoS path, the dmesg or kernel log will contain:
    

`kernel BUG at arch/x86/kvm/mmu/mmu.c:<line_number>`

`#Look specifically for function pte_list_remove`

`RIP: 0010:pte_list_remove+0x...`

**Monitor unusual KVM module activity from guests:**

*   In a KVM environment using nested virt, the host can observe guest operations with VMX/SVM:
    

`#On the host, monitor kernel audit log for kvm module events`

`auditctl -w /dev/kvm -p rw -k kvm_access`

**SIEM query pattern — Detect host panic related to KVM:**

`# Elasticsearch / Kibana (syslog ingestion)`

`event.dataset:syslog AND`

`message:("kernel BUG" OR "BUG: unable to handle") AND`

`message:"kvm"`

### **Detection —** Guest side (Lateral Detection)

If you operate from the guest side and suspect another tenant is attacking the host:

`#Check if the host suddenly reboots / crashes abnormally`

`#Compare uptime of all VMs with the same host`

`who -b`

`last reboot`

## Comments

CVSS 8.8 / 9.3 is an accurate reflection of technical severity — but the actual risk depends on a simple question: is your host running nested virtualization with an untrusted tenant?

Otherwise — for example, pure on-premise infrastructure, no multi-tenant guests, or all guest VMs controlled by the organization — the risk of active exploitation is significantly lower. Patching still needs to be done, but not as urgently as with a cloud provider.

On the contrary, if you operate a public cloud or multi-tenant private cloud on an x86 KVM platform — this is a serious problem that needs to be addressed immediately. Any tenant, with nothing more than root privileges in their VM (the default condition), can crash the entire host and take all other tenants' VMs with it. This is a DoS that requires absolutely no high skills — the PoC was public and live in minutes.

About the Vietnamese context: Domestic cloud infrastructure — from tier-3 data centers providing VPS services to private cloud enterprises — largely runs on KVM/x86 platform. More worrying is that nested virtualization is often enabled by default or by customer request without a clear security review process. This is a good time to double check the configuration and include "is nested virt enabled?" Go to the onboarding tenant checklist.

Notable Pattern from Hyunwoo Kim: In less than 2 months, Kim has announced three kernel exploits: DirtyFrag (CVE-2026-43284/CVE-2026-43500 — LPE via page cache, May 2026), ITScape (CVE-2026-46316 — First KVM escape on ARM64, June 2026), and Januscape (CVE-2026-53359 — KVM escape on x86, July 2026). These three exploits are not just personal achievements — they show that the KVM shadow paging codebase, which is legacy code that is less thoroughly reviewed, has more attack surface than the community thinks.

There's one more detail worth noting: CVE-2026-46113 — another MMU use-after-free shadow related to rmap mismatch — was fixed in May 2026, just one month before Januscape. Two use-after-frees in the same shadow paging code within two months is a clear signal that this is an area of ​​code that needs a deeper audit.

## Recommended Action

### Immediate (0–24 hours)

Step 1 — Check current kernel version:

`uname -r`

\=> Compare with the stable version table above

Step 2 — Confirm nested virtualization is enabled:

`cat /sys/module/kvm_intel/parameters/nested`

`cat /sys/module/kvm_amd/parameters/nested`

\=> Output "Y" or "1" = on = at risk

Step 3 — If you cannot patch immediately, turn off nested virt:

`echo "options kvm_intel nested=0" >> /etc/modprobe.d/kvm.conf`

`echo "options kvm_amd nested=0" >> /etc/modprobe.d/kvm.conf`

*   Apply now (if there is no running VM that needs to be nested virt)
    

`modprobe -r kvm_intel && modprobe kvm_intel nested=0`

`modprobe -r kvm_amd && modprobe kvm_amd nested=0`

Step 4 — Check /dev/kvm permission (if RHEL-based host):

`ls -la /dev/kvm`

\=> If output is crw-rw-rw- (0666) → unprivileged user in guest can LPE

\=> Consider restricting to 0660 if not needed

### Short-term (1–7 days)

*   Patch the kernel to the fixed stable version according to the table above
    
*   For distributions without backports (Debian stable/bookworm, RHEL): monitor vendor tracker and apply as soon as available
    
*   Review all x86 KVM hosts in the fleet — build a list of hosts with nested=1 and multi-tenant guests
    
*   If using automation (Ansible, Puppet), add the kvm\_intel.nested check task to the inventory scan
    

### **Long-term**

*   Review the policy to enable nested virtualization: Many tenants do not really need nested virtualization. Turning it off by default and turning it on as required with documented justification is a safer approach.
    
*   Audit shadow paging code: With two CVEs in two months in the same code area, this is the time for the organization to consider contributing to a kernel review or closely monitor commits related to arch/x86/kvm/mmu/.
    
*   Monitor /dev/kvm permission in all guest templates: Especially with default 0666 distros like RHEL — restrict to 0660 to remove unnecessary LPE paths.
    
*   Consider deploying QEMU / KVM on a separate host for multi-tenant workloads with high security requirements, separate from shared infrastructure.
    

## Lookup table & Link updates patches according to each Distribution

### Upstream Linux Kernel

*   **Patch the main commit:** [81ccda30b4e8](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=81ccda30b4e83d8f5cc4fd50503c44e3a33abfeb)
    
*   **Companion fix:** `0cb2af2ea66a`
    

| **Branch** | **Fixed version** | **Source download link** |
| --- | --- | --- |
| v7.x | ≥ **7.1.3** | [kernel.org/pub/linux/kernel/v7.x](https://www.kernel.org/pub/linux/kernel/v7.x/) |
| v6.18.x | ≥ **6.18.38** | [kernel.org/pub/linux/kernel/v6.x](https://www.kernel.org/pub/linux/kernel/v6.x/) |
| v6.12.x (LTS) | ≥ **6.12.95** | [kernel.org/pub/linux/kernel/v6.x](https://www.kernel.org/pub/linux/kernel/v6.x/) |
| v6.6.x (LTS) | ≥ **6.6.144** | [kernel.org/pub/linux/kernel/v6.x](https://www.kernel.org/pub/linux/kernel/v6.x/) |
| v6.1.x (LTS) | ≥ **6.1.177** | [kernel.org/pub/linux/kernel/v6.x](https://www.kernel.org/pub/linux/kernel/v6.x/) |
| v5.15.x (LTS) | ≥ **5.15.211** | [kernel.org/pub/linux/kernel/v5.x](https://www.kernel.org/pub/linux/kernel/v5.x/) |
| v5.10.x (LTS) | ≥ **5.10.260** | [kernel.org/pub/linux/kernel/v5.x](https://www.kernel.org/pub/linux/kernel/v5.x/) |

### Debian — Fixed

*   **Advisory:** [DSA-6381-1](https://www.debian.org/security/2026/dsa-6381)
    
*   **Tracker:** [security-tracker.debian.org](http://security-tracker.debian.org)
    
*   **Fixed version:** `linux 7.1.3-1` (unstable/sid), `linux 6.12.95-1` (testing/trixie), `linux 5.10.223-1` (oldstable/bullseye).
    
*   **Update command:** `sudo apt-get update && sudo apt-get upgrade linux-image-$(uname -r)`
    

### Red Hat / RHEL — Fixed

*   **Advisory:** [RHSA-2026:36957](https://access.redhat.com/errata/RHSA-2026:36957) (mức Important)
    
*   **Tracker:** [access.redhat.com/security/cve/cve-2026-53359](https://access.redhat.com/security/cve/cve-2026-53359)
    
*   **Fixed version:** RHEL 9: `kernel-5.14.0-687.23.1.el9_8` or higher.
    
*   **Update command:** `sudo dnf update kernel && sudo reboot`
    

### AlmaLinux — Fixed

*   **Advisory:** [ALSA-2026:36957](https://errata.almalinux.org/9/ALSA-2026-36957.html) (AlmaLinux 9), [ALSA-2026:36956](https://errata.almalinux.org/10/ALSA-2026-36956.html) (AlmaLinux 10)
    
*   **Fixed version:** AL9: `kernel-5.14.0-687.23.1.el9_8`; AL10: `kernel-6.12.0-211.32.1.el10_2`.
    
*   **Update command:** `sudo dnf update kernel && sudo reboot`
    

### Rocky Linux — Fixed

*   **Advisory:** [RLSA-2026:36957](https://errata.rockylinux.org/RLSA-2026:36957) (Rocky Linux 9), [RLSA-2026:36956](https://errata.rockylinux.org/) (Rocky Linux 10)
    
*   **Fixed version:** RL9: `kernel-5.14.0-687.24.1.el9_8`; RL10: `kernel-6.12.0-211.32.1.el10_2`.
    
*   **Update command:** `sudo dnf update kernel && sudo reboot`
    

### Oracle Linux — Fixed

*   **Advisory:** [ELSA-2026-36957](https://linux.oracle.com/errata/ELSA-2026-36957.html) (Oracle Linux 9), [ELSA-2026-39083](https://linux.oracle.com/errata/ELSA-2026-39083.html) (Oracle Linux 8)
    

### Fedora — Fixed

*   **Advisory:** [FEDORA-2026-c3e2e91b4d](https://bodhi.fedoraproject.org/updates/FEDORA-2026-c3e2e91b4d) (Fedora 43)
    
*   **Tracker:** [bodhi.fedoraproject.org](http://bodhi.fedoraproject.org)
    
*   **Update command:** `sudo dnf update kernel && sudo reboot`
    

### Arch Linux — Fixed

*   **Tracker:** [security.archlinux.org](http://security.archlinux.org)
    
*   **Update command:** `sudo pacman -Syu`
    

### Ubuntu — Pending (No official patch has been released yet)

*   **Tracker:** [ubuntu.com/security/CVE-2026-53359](https://ubuntu.com/security/CVE-2026-53359)
    
*   **Note:** Canonical is preparing a patch. Please follow the link above for updates as soon as USN is released.
    

### SUSE / openSUSE — Pending (No official patch has been released yet)

*   **Bug tracker:** bsc#1270059
    
*   **Tracker:** [suse.com/security/cve/CVE-2026-53359](https://www.suse.com/security/cve/CVE-2026-53359.html) (SLE 15 SP7, openSUSE Leap)
    
*   Update command (after release**:** `sudo zypper refresh && sudo zypper patch`
    

### Other Distributions

*   Amazon Linux: See alas.aws.amazon.com (search for CVE-2026-53359)
    
*   Gentoo: See security.gentoo.org/glsa (search for CVE-2026-53359)
    

## Reference

[16-Year-Old Linux KVM Flaw Lets Guest VMs Escape to Host on Intel and AMD x86 Systems](https://thehackernews.com/2026/07/16-year-old-linux-kvm-flaw-lets-guest.html)

[V4bel (@v4bel) / X](https://x.com/v4bel)

[security-research/pocs/linux/kernelctf/CVE-2024-50264\_lts\_cos/docs/](https://github.com/google/security-research/blob/09335abb6b01ee706a5a5584278ef4c4c1d50bda/pocs/linux/kernelctf/CVE-2024-50264_lts_cos/docs/exploit.md)[exploit.md](http://exploit.md) [at 09335abb6b01ee706a5a5584278ef4c4c1d50bda · google/security-research · GitHub](https://github.com/google/security-research/blob/09335abb6b01ee706a5a5584278ef4c4c1d50bda/pocs/linux/kernelctf/CVE-2024-50264_lts_cos/docs/exploit.md)

[New Januscape Linux flaw allows VM escape on Intel, AMD devices](https://www.bleepingcomputer.com/news/linux/new-januscape-linux-kernel-flaw-allows-vm-escape-on-intel-amd-devices/)
