KVM: nVMX: check for invalid hdr.vmx.flags
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 27 Jul 2020 12:55:09 +0000 (08:55 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 27 Jul 2020 13:04:50 +0000 (09:04 -0400)
hdr.vmx.flags is meant for future extensions to the ABI, rejecting
invalid flags is necessary to avoid broken half-loads of the
nVMX state.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx/nested.c
tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c

index 6a0e32a..11e4df5 100644 (file)
@@ -6079,6 +6079,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
            ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON))
                return -EINVAL;
 
+       if (kvm_state->hdr.vmx.flags & ~KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE)
+               return -EINVAL;
+
        /*
         * SMM temporarily disables VMX, so we cannot be in guest mode,
         * nor can VMLAUNCH/VMRESUME be pending.  Outside SMM, SMM flags
index 94f28a6..d59f3eb 100644 (file)
@@ -146,6 +146,11 @@ void test_vmx_nested_state(struct kvm_vm *vm)
        state->hdr.vmx.smm.flags = 1;
        test_nested_state_expect_einval(vm, state);
 
+       /* Invalid flags are rejected. */
+       set_default_vmx_state(state, state_sz);
+       state->hdr.vmx.flags = ~0;
+       test_nested_state_expect_einval(vm, state);
+
        /* It is invalid to have vmxon_pa == -1ull and vmcs_pa != -1ull. */
        set_default_vmx_state(state, state_sz);
        state->hdr.vmx.vmxon_pa = -1ull;
@@ -206,6 +211,14 @@ void test_vmx_nested_state(struct kvm_vm *vm)
        state->flags = 0;
        test_nested_state(vm, state);
 
+       /* Invalid flags are rejected, even if no VMCS loaded. */
+       set_default_vmx_state(state, state_sz);
+       state->size = sizeof(*state);
+       state->flags = 0;
+       state->hdr.vmx.vmcs12_pa = -1;
+       state->hdr.vmx.flags = ~0;
+       test_nested_state_expect_einval(vm, state);
+
        /* vmxon_pa cannot be the same address as vmcs_pa. */
        set_default_vmx_state(state, state_sz);
        state->hdr.vmx.vmxon_pa = 0;