Patch "KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4" has been added to the 5.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4

to the 5.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     kvm-nvmx-inject-ud-if-vmxon-is-attempted-with-incomp.patch
and it can be found in the queue-5.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 452c457abb5411372c478172ce17b997bce37923
Author: Sean Christopherson <seanjc@xxxxxxxxxx>
Date:   Tue Jun 7 21:35:52 2022 +0000

    KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4
    
    [ Upstream commit c7d855c2aff2d511fd60ee2e356134c4fb394799 ]
    
    Inject a #UD if L1 attempts VMXON with a CR0 or CR4 that is disallowed
    per the associated nested VMX MSRs' fixed0/1 settings.  KVM cannot rely
    on hardware to perform the checks, even for the few checks that have
    higher priority than VM-Exit, as (a) KVM may have forced CR0/CR4 bits in
    hardware while running the guest, (b) there may incompatible CR0/CR4 bits
    that have lower priority than VM-Exit, e.g. CR0.NE, and (c) userspace may
    have further restricted the allowed CR0/CR4 values by manipulating the
    guest's nested VMX MSRs.
    
    Note, despite a very strong desire to throw shade at Jim, commit
    70f3aac964ae ("kvm: nVMX: Remove superfluous VMX instruction fault checks")
    is not to blame for the buggy behavior (though the comment...).  That
    commit only removed the CR0.PE, EFLAGS.VM, and COMPATIBILITY mode checks
    (though it did erroneously drop the CPL check, but that has already been
    remedied).  KVM may force CR0.PE=1, but will do so only when also
    forcing EFLAGS.VM=1 to emulate Real Mode, i.e. hardware will still #UD.
    
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=216033
    Fixes: ec378aeef9df ("KVM: nVMX: Implement VMXON and VMXOFF")
    Reported-by: Eric Li <ercli@xxxxxxxxxxx>
    Cc: stable@xxxxxxxxxxxxxxx
    Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
    Message-Id: <20220607213604.3346000-4-seanjc@xxxxxxxxxx>
    Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 30babb471ae3..f3b500b8475f 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4964,20 +4964,25 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
 		| FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
 
 	/*
-	 * The Intel VMX Instruction Reference lists a bunch of bits that are
-	 * prerequisite to running VMXON, most notably cr4.VMXE must be set to
-	 * 1 (see vmx_is_valid_cr4() for when we allow the guest to set this).
-	 * Otherwise, we should fail with #UD.  But most faulting conditions
-	 * have already been checked by hardware, prior to the VM-exit for
-	 * VMXON.  We do test guest cr4.VMXE because processor CR4 always has
-	 * that bit set to 1 in non-root mode.
+	 * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
+	 * that have higher priority than VM-Exit (see Intel SDM's pseudocode
+	 * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
+	 * running the guest, i.e. KVM needs to check the _guest_ values.
+	 *
+	 * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
+	 * !COMPATIBILITY modes.  KVM may run the guest in VM86 to emulate Real
+	 * Mode, but KVM will never take the guest out of those modes.
 	 */
-	if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
+	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
 		kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
 	}
 
-	/* CPL=0 must be checked manually. */
+	/*
+	 * CPL=0 and all other checks that are lower priority than VM-Exit must
+	 * be checked manually.
+	 */
 	if (vmx_get_cpl(vcpu)) {
 		kvm_inject_gp(vcpu, 0);
 		return 1;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux