Memory safety: buffer underflow in KVM SEV MMIO path

MEDIUM
torvalds/linux
Commit: 1aa8a6dc7dac
Affected: v7.0-rc6 (KVM SEV MMIO path; patch targets 0-length MMIO handling in sev_handle_vmgexit).
2026-05-30 10:40 UTC

Description

The commit adds a guard to ignore MMIO requests with length 0 in the KVM SEV MMIO exit path. Prior to the patch, a length of 0 could lead to unsafe length-based calculations (e.g., computing end pointers or scratch area setup) that might underflow and cause memory corruption or other memory-safety issues. The patch returns early when len == 0, and continues using len for subsequent scratch setup and MMIO handling only when len is non-zero. This is a defensive fix for a potential buffer underflow in the SEV MMIO path and reduces the risk of memory corruption stemming from zero-length MMIO handling.

Proof of Concept

This demonstrates the underlying risk pattern in a safe, user-space simulation (not a kernel exploit): #include <stdio.h> #include <stdint.h> // Vulnerable-like simulation: zero-length path leads to end pointer underflow int vulnerable_sim() { unsigned char buf[64]; unsigned long long len = 0; // simulate 0-length MMIO unsigned char *start = buf; unsigned char *end = start + len - 1; // underflow when len == 0 // Unsafe access that would occur in the vulnerable path *end = 'A'; return 0; } // Patched behavior: 0-length MMIO is ignored int patched_sim() { unsigned char buf[64]; unsigned long long len = 0; // simulate 0-length MMIO if (len == 0) { // ignore 0-length MMIO requests return 0; } unsigned char *start = buf; unsigned char *end = start + len - 1; *end = 'A'; return 0; } int main(){ vulnerable_sim(); patched_sim(); return 0; }

Commit Details

Author: Sean Christopherson

Date: 2026-05-01 20:22 UTC

Message:

KVM: SEV: Ignore MMIO requests of length '0' Explicitly ignore MMIO requests of length '0', so that setting up the software scratch area (and other code) doesn't have to worry about underflowing the length, and to allow for special casing '0' in the future. Fixes: 8f423a80d299 ("KVM: SVM: Support MMIO for an SEV-ES guest") Cc: stable@vger.kernel.org Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260501202250.2115252-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Triage Assessment

Vulnerability Type: Memory safety (buffer underflow)

Confidence: MEDIUM

Reasoning:

The patch adds a guard to ignore MMIO requests with length 0, preventing potential underflow and memory-safety issues when setting up the scratch area and handling MMIO. This reduces the risk of memory corruption or related exploits stemming from zero-length MMIO handling.

Verification Assessment

Vulnerability Type: Memory safety: buffer underflow in KVM SEV MMIO path

Confidence: MEDIUM

Affected Versions: v7.0-rc6 (KVM SEV MMIO path; patch targets 0-length MMIO handling in sev_handle_vmgexit).

Code Diff

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 23170b64f4a33d..fb2174b6d1ba43 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -4497,13 +4497,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) case SVM_VMGEXIT_MMIO_READ: case SVM_VMGEXIT_MMIO_WRITE: { bool is_write = control->exit_code == SVM_VMGEXIT_MMIO_WRITE; + u64 len = control->exit_info_2; - ret = setup_vmgexit_scratch(svm, !is_write, control->exit_info_2); + if (!len) + return 1; + + ret = setup_vmgexit_scratch(svm, !is_write, len); if (ret) break; - ret = kvm_sev_es_mmio(vcpu, is_write, control->exit_info_1, - control->exit_info_2, svm->sev_es.ghcb_sa); + ret = kvm_sev_es_mmio(vcpu, is_write, control->exit_info_1, len, + svm->sev_es.ghcb_sa); break; } case SVM_VMGEXIT_NMI_COMPLETE:
← Back to Alerts View on GitHub →