A dangerous vulnerability, tracked as CVE-2023-4155, was found in the Linux kernel KVM module, affecting systems using AMD’s Secure Encrypted Virtualization features (SEV-ES and SEV-SNP). This bug can, under the right conditions, lead to a stack overflow — even opening the door to a guest-to-host escape under some kernel configurations, where no stack guard page is present. In this post, I’ll break down how this flaw works, show relevant code, share links to patches and advisories, and explain the risk in plain language.
What is KVM, SEV, SEV-ES, and SEV-SNP?
- KVM: Kernel-based Virtual Machine, a core Linux component, allows running virtual machines (VMs) on Linux.
- SEV/SEV-ES/SNP: AMD’s Secure Encrypted Virtualization extensions. These secure VMs by encrypting memory and adding integrity protections.
Linux Kernel 5.x, 6.x (before having the patch applied)
- Especially dangerous if CONFIG_VMAP_STACK is disabled (this removes extra kernel stack protections)
Summary of the Vulnerability
A double fetch race condition exists in KVM’s handling code for the VMGEXIT handler, a mechanism by which a VM can ask the host kernel to handle a secure event (like an emulated instruction).
By manipulating vCPUs in a coordinated way, a malicious guest can cause the sev_handle_vmgexit() (or equivalent) function to recursively call itself. Given no stack guard page, this recursion can overflow the kernel stack, potentially leading to a denial-of-service (DoS) or, in the worst cases, arbitrary code execution in the kernel — allowing a VM escape.
How the Bug Works
The kernel’s SEV logic expects certain information from the guest when it issues a VMGEXIT. Due to a flaw in the synchronization and memory handling, two vCPUs can race — each can be in a state where it believes it should process certain data, and both can cause recursive kernel calls to the same handler.
This is known as a double fetch: the same memory data is fetched by the kernel multiple times, but in between fetches, the data can be changed (raced on) by another CPU.
From the Red Hat advisory
> "... A KVM guest using SEV-ES or SEV-SNP with multiple vCPUs can trigger a double fetch race condition vulnerability and invoke the VMGEXIT handler recursively. ..."
The vulnerability lies in the SEV-specific KVM handler for VMGEXITs, like the following pseudo-code
// Simplified - handler logic exposed to race
int sev_handle_vmgexit(struct kvm_vcpu *vcpu) {
// ...snipped setup...
struct sev_es_save_area *area = get_save_area(vcpu);
// Double fetch! Another vCPU could modify *area here
if (area->event_injection_request) {
// Calls sev_handle_vmgexit() again on the same vCPU
sev_handle_vmgexit(vcpu);
}
// ...snipped more logic...
}
A malicious guest can set up its vCPUs so both attempt to inject events in a race, forcing recursive stack use.
## How to Trigger the Vulnerability / Exploit Details
Although public exploit code may not exist yet, the logic is simple
1. Start a KVM guest with two or more vCPUs, SEV-ES/SNP enabled.
2. Coordinate the two vCPUs: Have vCPU1 set up a VMGEXIT, while vCPU2 rapidly changes the event injection request region. This double fetch can confuse the kernel.
3. The kernel falls into recursive sev_handle_vmgexit() calls. With stack guard pages disabled (CONFIG_VMAP_STACK not set), the kernel stack can overflow.
Denial of Service: The host kernel can crash (oops, panic).
- VM Escape (theoretical, likely with extra bugs): If further kernel protections are not present, and stack contents (like return addresses) are controllable, code execution is possible.
Proof-of-concept:
Here’s a simple illustration (not an actual exploit, but a demonstration concept)
void *malicious_thread(void *arg) {
for (;;) {
// Trigger event injection request
setup_event_injection();
vmgexit();
}
return NULL;
}
int main() {
// Spin up multiple threads, simulating multiple vCPUs
pthread_t t1, t2;
pthread_create(&t1, NULL, malicious_thread, NULL);
pthread_create(&t2, NULL, malicious_thread, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
In reality, the setup and triggering would be done via low-level VM instructions, but this conveys the attack’s flavor.
Real World Impact
- Cloud providers using AMD SEV/SEV-SNP for customer VMs: At risk for VM escapes or host crashes.
On-prem hypervisors with multiple tenants: A rogue tenant could crash or compromise the host.
- Desktop/Development use: Unlikely, unless running malicious code as guest OSes.
Patch and Mitigation
Patch:
The Linux kernel community patched this bug in versions after commit.
- Upstream patch in kernel.org
- Red Hat Security Advisory
- Ubuntu CVE Tracker
Update your host kernel! Always run the latest patched kernel.
- Enable CONFIG_VMAP_STACK when building the kernel; this makes stack overflow much harder to exploit.
- Restrict untrusted tenants/guests from running untrusted code in privileged VMs.
Final Thoughts
CVE-2023-4155 is a subtle but nasty bug — a classic example of why virtualization, just like any system software, demands constant scrutiny for race conditions and complex corner cases. For sysadmins or kernel builders running AMD SEV-ES/SNP guests, updating your kernel or applying vendor patches is urgent.
Links and References
- CVE-2023-4155 at Mitre
- Red Hat advisory
- Upstream kernel patch
- Kernel KVM SEV code
- SEV documentation (kernel.org)
Stay safe and always patch! If you have questions about this flaw or kernel virtualization in general, feel free to ask below.
Timeline
Published on: 09/13/2023 17:15:10 UTC
Last modified on: 11/07/2023 04:22:11 UTC