KVM SEV-SNP Page State Change (PSC) Heap Out-of-Bounds — CVE-2026-53360
by 0xCyberstan (writeup: cyberstan.co.uk) · 2026-07-05
- Severity
- High (guest-to-host host kernel heap corruption / info leak)
- CVE
- CVE-2026-53360
- Category
- binary
- Affected product
- Linux KVM host, SEV-SNP support (arch/x86/kvm/svm/sev.c, snp_begin_psc() / setup_vmgexit_scratch())
- Affected versions
- Introduced in commit 9b54e248d264 (~v6.10, first KVM SNP PSC handling); fixed by commit db3f219 (mainline, tagged Fixes: 4af663c, backported to stable). Tested vulnerable on host kernel 6.11.11.
- Disclosed
- 2026-07-05
- Patch status
- unpatched
Tags
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-05 |
| Author / Researcher | 0xCyberstan (writeup: cyberstan.co.uk) |
| CVE / Advisory | CVE-2026-53360 |
| Category | binary |
| Severity | High (guest-to-host host kernel heap corruption / info leak) |
| CVSS Score | Not disclosed |
| Status | PoC |
| Tags | kvm, sev-snp, kernel, heap-oob, kasan, guest-escape, slab, kmalloc-cg, linux-kernel, cwe-125, cwe-787 |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Linux KVM host, SEV-SNP support (arch/x86/kvm/svm/sev.c, snp_begin_psc() / setup_vmgexit_scratch()) |
| Versions Affected | Introduced in commit 9b54e248d264 (~v6.10, first KVM SNP PSC handling); fixed by commit db3f219 (mainline, tagged Fixes: 4af663c, backported to stable). Tested vulnerable on host kernel 6.11.11. |
| Language / Platform | C — Linux kernel module (trigger.c) run inside an SEV-SNP guest, attacking the KVM host via GHCB VMGEXIT requests |
| Authentication Required | No (any code running inside an SEV-SNP guest, including as a kernel module the guest owner loads) |
| Network Access Required | No (local guest-to-hypervisor channel via GHCB, not network-based) |
Summary
KVM’s SEV-SNP Page State Change (PSC) handler trusts a guest-supplied entry count against a fixed protocol constant (VMGEXIT_PSC_MAX_COUNT = 253) instead of validating it against the actual size of the buffer the host allocated for the request. When a guest points its GHCB scratch area outside the shared GHCB buffer, the host allocates a kmalloc-cg-backed buffer sized exactly to the guest-supplied length, but still permits the guest to specify an end index up to 253 entries. This lets a malicious SEV-SNP guest walk past the end of a small (e.g. 32-byte) slab allocation, reading and partially overwriting adjacent kernel heap objects on repeated requests. The included PoC is a guest kernel module that, on load, runs four escalating stages (heap-layout disclosure, persistence-of-write verification, extended OOB read, and a KASAN-triggering sweep) purely by crafting malformed PSC requests from inside the guest.
Vulnerability Details
Root Cause
In snp_begin_psc(), the entry-index bound check validates hdr->end_entry against the protocol-level constant VMGEXIT_PSC_MAX_COUNT (253) rather than against the size of the buffer actually allocated by setup_vmgexit_scratch() for an out-of-GHCB scratch area (kvzalloc(len, GFP_KERNEL_ACCOUNT), where len is guest-controlled via SW_EXITINFO2). A guest that requests a small scratch buffer (e.g. 24 bytes, fitting only 2 entries) but sets end_entry up to 252 causes the host to read/write far past the allocation boundary (CWE-125 / CWE-787).
Attack Vector
- From inside an SEV-SNP guest, construct a GHCB PSC VMGEXIT request whose
SW_SCRATCHpoints outside the GHCB’s shared buffer, forcing the host to allocate a small dedicated buffer sized by the guest-controlledSW_EXITINFO2length. - Set the PSC descriptor’s
end_entryfield beyond the number of entries that actually fit in the allocated buffer (up to the protocol max of 253). - Repeat VMGEXIT requests, incrementing/probing the out-of-bounds index, to read adjacent slab memory contents (heap layout disclosure) and, when a decoded OOB entry validates as a
KVM_HC_MAP_GPA_RANGE, trigger a small constrained write back into that OOB slot. - Repeat across many requests (each re-allocating the scratch buffer) to sweep across different neighboring slab objects, enabling heap layout disclosure, a constrained write primitive, and use-after-free conditions.
Impact
A malicious or compromised SEV-SNP guest can corrupt and read the host kernel’s heap memory (specifically kmalloc-cg-32 slab objects), undermining the flip side of SEV-SNP’s threat model (guest is untrusted by design, but the host must still defend against a hostile guest). This can lead to host kernel information disclosure, memory corruption, denial of service (host crash), and is a foothold for further host kernel exploitation.
Environment / Lab Setup
Target: Bare-metal AMD EPYC (Milan/Genoa/Bergamo/Siena/Turin) host with SEV-SNP enabled,
KVM host kernel built with CONFIG_KASAN=y, booted with kvm_amd.sev_snp=1 kasan_multi_shot
Attacker: SNP-capable QEMU fork (AMDESE/qemu, snp-latest branch) + SNP OVMF firmware,
Linux guest with build-essential/linux-headers to build trigger.ko
Proof of Concept
PoC Script
See
trigger.candMakefilein this folder.
| |
trigger.c is a guest kernel module that checks for SEV-SNP via CPUID, allocates a decrypted scratch page, hand-builds malformed GHCB PSC requests, and runs four stages: (1) probing 48 out-of-bounds entries to map host heap layout, (2) verifying an OOB write persists across VMGEXITs, (3) measuring how far an OOB read reaches, and (4) firing 200 requests designed to trip KASAN reports on the host. It returns -EAGAIN from init so it unloads itself automatically after running.
Detection & IOCs
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199
The buggy address belongs to the object at ffff888XXXXXXXXX
which belongs to the cache kmalloc-cg-32 of size 32
Signs of compromise:
- Host
dmesg/KASAN reports referencingsnp_begin_pscslab-out-of-bounds or slab-use-after-free againstkmalloc-cg-32 - Repeated PSC VMGEXITs from a guest with a scratch area pointing outside the GHCB shared buffer and abnormally high
end_entryvalues relative to declared length - Unexplained host kernel instability/crashes correlated with a specific SEV-SNP guest VM
Remediation
| Action | Detail |
|---|---|
| Primary fix | Apply upstream commit db3f219, which rejects any out-of-GHCB scratch area for GHCB v2+ guests in setup_vmgexit_scratch(), pinning the buffer to a fixed known size, and additionally bounds the entry count against the real buffer size while re-reading the descriptor via READ_ONCE() |
| Interim mitigation | Until patched, restrict which guests can run under SEV-SNP on a given host, monitor host KASAN/dmesg for snp_begin_psc faults, and treat any SEV-SNP guest as capable of host kernel heap interaction |
References
- Source repository
- Full writeup: https://cyberstan.co.uk/sev-snp-oob/
Notes
Mirrored from https://github.com/0xCyberstan/CVE-2026-53360-POC on 2026-07-05. This PoC requires real AMD SEV-SNP hardware (bare metal EPYC 7003+) and cannot be reproduced on Intel or under nested virtualization; it was not executed as part of this archival/mirroring pass, only reviewed. LICENSE (GPL-2.0, matching the kernel module’s MODULE_LICENSE) was excluded from the mirror per archive convention.
| |