Skip to content

Commit ed129ec

Browse files
Maxim Levitskybonzini
authored andcommitted
KVM: x86: forcibly leave nested mode on vCPU reset
While not obivous, kvm_vcpu_reset() leaves the nested mode by clearing 'vcpu->arch.hflags' but it does so without all the required housekeeping. On SVM, it is possible to have a vCPU reset while in guest mode because unlike VMX, on SVM, INIT's are not latched in SVM non root mode and in addition to that L1 doesn't have to intercept triple fault, which should also trigger L1's reset if happens in L2 while L1 didn't intercept it. If one of the above conditions happen, KVM will continue to use vmcb02 while not having in the guest mode. Later the IA32_EFER will be cleared which will lead to freeing of the nested guest state which will (correctly) free the vmcb02, but since KVM still uses it (incorrectly) this will lead to a use after free and kernel crash. This issue is assigned CVE-2022-3344 Cc: stable@vger.kernel.org Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20221103141351.50662-5-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent f9697df commit ed129ec

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

arch/x86/kvm/x86.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12003,8 +12003,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
1200312003
WARN_ON_ONCE(!init_event &&
1200412004
(old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
1200512005

12006+
/*
12007+
* SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
12008+
* possible to INIT the vCPU while L2 is active. Force the vCPU back
12009+
* into L1 as EFER.SVME is cleared on INIT (along with all other EFER
12010+
* bits), i.e. virtualization is disabled.
12011+
*/
12012+
if (is_guest_mode(vcpu))
12013+
kvm_leave_nested(vcpu);
12014+
1200612015
kvm_lapic_reset(vcpu, init_event);
1200712016

12017+
WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
1200812018
vcpu->arch.hflags = 0;
1200912019

1201012020
vcpu->arch.smi_pending = 0;

0 commit comments

Comments
 (0)