Skip to main content

Command Palette

Search for a command to run...

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

Updated
20 min readView as Markdown
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

Criteria

Details (Januscape Vulnerability)

CVE

CVE-2026-53359

Product

KVM (Kernel-based Virtual Machine) virtualization module in the Linux kernel (exists since August 2010, supports both Intel and AMD CPUs).

CWE

CWE-416 (Use-After-Free).

CVSS 3.1

Severity: Critical/High

Prerequisites

1. The physical server (Host) allows/enables Nested Virtualization.

2. The attacker must obtain the highest privileges (root) inside the guest virtual machine (Guest VM).

Exploitation

Guest-to-Host Escape: 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).

Discovered by

Security researcher Hyunwoo Kim (alias @v4bel).

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.

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.

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.

Configuration

Memory mechanism

Can Januscape exploit it?

Regular KVM (non-nested)

EPT/NPT (hardware)

No

KVM with nested virtualization enabled

Shadow paging (software)

Yes

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

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

Variable Name

Data Type

Value

Meaning / Description

amd

static int

0

Virtualization architecture routing: 0 for Intel VMX, 1 for AMD SVM.

nvcpu

static int

8

Number of vCPU threads participating in the race condition process.

dwell

static int

256

Sleep time (in microseconds - µs) of the WRITER thread in each loop iteration.

run_ms

static int

600000

Maximum lifetime (timeout) of the entire PoC (600,000 ms = 10 minutes).

diag

static int

1

Flag to enable printing diagnostic error logs to the screen (1 = On).

nflood

static int

0

Number of extra "flood" threads spawned to increase pressure (load) on the system.

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:

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.

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:

next_grip() protocols the PDE toggling continuously between two states:

Call

PDE Value

Required shadow page

role.direct

Calls 1, 9, 17... (mod 8 = 0)

Large 2MB (PS=1)

direct=1

1

Calls 2–8, 10–16...

Small 4KB table

direct=0

0

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:

WRITER thread runs a tight loop:

FAULT thread trigger page fault at GVA_PRIME in L2:

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:

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:

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:

Intel path

AMD path (amd=1)

Instruction set

VMX: vmxon, vmwrite, vmlaunch

SVM: vmrun, VMCB struct

Nested EPT/NPT config

EPT Pointer register

VMCB nested_ctl / misc_ctl

Code in PoC

intel_cpu_on(), intel_vcpu_run()

svm_cpu_on(), svm_vcpu_run()

Host KVM bug path

Same — kvm_mmu_get_child_sp()

Same

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):

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

Milestone

Date

Details

Bug introduced

01/08/2010

Commit 2032a93d66fa, Linux 2.6.36

Kim submitted kvmCTF

Before 06/2026

Used as 0-day, full escape

Embargo started

Before 06/2026

Report sent to linux-distros@vs.openwall.org

Patch merged to mainline

19/06/2026

Commit 81ccda30b4e8 by Paolo Bonzini

Embargo ended

06/07/2026

Disclosed on oss-security

Stable kernels patched

04/07/2026

7 stable branches

PoC public

06/07/2026

GitHub V4bel/Januscape

Debian DSA-6381-1

05/07/2026

testing/trixie and unstable/sid

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

Tactic

Technique

Relevance

Privilege Escalation

T1611 – Escape to Host

Core technique — escape from guest VM to host

Privilege Escalation

T1068 – Exploitation for Privilege Escalation

Kernel UAF to escalate to root privileges

Execution

T1059.004 – Command and Scripting Interpreter: Unix Shell

Execute after getting a shell on the host

Impact

T1499.004 – Endpoint Denial of Service: Application or System Exploitation

DoS path — crash host kernel

Defense Evasion

T1014 – Rootkit

Potential after getting host root, establish persistence

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.

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.

Upstream Linux Kernel

  • Patch the main commit: 81ccda30b4e8

  • Companion fix: 0cb2af2ea66a

Branch Fixed version Source download link
v7.x 7.1.3 kernel.org/pub/linux/kernel/v7.x
v6.18.x 6.18.38 kernel.org/pub/linux/kernel/v6.x
v6.12.x (LTS) 6.12.95 kernel.org/pub/linux/kernel/v6.x
v6.6.x (LTS) 6.6.144 kernel.org/pub/linux/kernel/v6.x
v6.1.x (LTS) 6.1.177 kernel.org/pub/linux/kernel/v6.x
v5.15.x (LTS) 5.15.211 kernel.org/pub/linux/kernel/v5.x
v5.10.x (LTS) 5.10.260 kernel.org/pub/linux/kernel/v5.x

Debian — Fixed

  • Advisory: DSA-6381-1

  • Tracker: 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

AlmaLinux — Fixed

  • Advisory: ALSA-2026:36957 (AlmaLinux 9), ALSA-2026:36956 (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 (Rocky Linux 9), RLSA-2026:36956 (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

Fedora — Fixed

Arch Linux — Fixed

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

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

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

V4bel (@v4bel) / X

security-research/pocs/linux/kernelctf/CVE-2024-50264_lts_cos/docs/exploit.md at 09335abb6b01ee706a5a5584278ef4c4c1d50bda · google/security-research · GitHub

New Januscape Linux flaw allows VM escape on Intel, AMD devices

More from this blog

F

FPT IS Security

981 posts

Dedicated to providing insightful articles on cybersecurity threat intelligence, aimed at empowering individuals and organizations to navigate the digital landscape safely.