From: Sean Christopherson Date: Wed, 25 Feb 2026 01:20:42 +0000 (-0800) Subject: KVM: x86: Harden SEV-ES MMIO against on-stack use-after-free X-Git-Tag: v7.1-rc1~118^2~7^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=144089f5c3944cf6383d53ab5d941b74924a0989;p=thirdparty%2Flinux.git KVM: x86: Harden SEV-ES MMIO against on-stack use-after-free Add a sanity check to ensure KVM doesn't use an on-stack variable when handling an MMIO request for an SEV-ES guest. The source/destination for SEV-ES MMIO should _always_ be the #VMGEXIT scratch area. Opportunistically update the comment in the completion side of things to clarify that frag->data doesn't need to be copied anywhere, and the VMEGEXIT is trap-like (the current comment doesn't clarify *how* RIP is advanced). Tested-by: Tom Lendacky Tested-by: Rick Edgecombe Link: https://patch.msgid.link/20260225012049.920665-8-seanjc@google.com Signed-off-by: Sean Christopherson --- diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0f4cfc3374a68..5752ec3fc8f2f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -14272,8 +14272,10 @@ static int complete_sev_es_emulated_mmio(struct kvm_vcpu *vcpu) if (vcpu->mmio_cur_fragment >= vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; - // VMG change, at this point, we're always done - // RIP has already been advanced + /* + * All done, as frag->data always points at the GHCB scratch + * area and VMGEXIT is trap-like (RIP is advanced by hardware). + */ return 1; } @@ -14296,7 +14298,7 @@ int kvm_sev_es_mmio_write(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned int bytes, int handled; struct kvm_mmio_fragment *frag; - if (!data) + if (!data || WARN_ON_ONCE(object_is_on_stack(data))) return -EINVAL; handled = write_emultor.read_write_mmio(vcpu, gpa, bytes, data); @@ -14335,7 +14337,7 @@ int kvm_sev_es_mmio_read(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned int bytes, int handled; struct kvm_mmio_fragment *frag; - if (!data) + if (!data || WARN_ON_ONCE(object_is_on_stack(data))) return -EINVAL; handled = read_emultor.read_write_mmio(vcpu, gpa, bytes, data);