KVM: nVMX: Add a WARN for freeing a loaded VMCS02
authorMark Kanda <mark.kanda@oracle.com>
Mon, 27 Nov 2017 23:22:26 +0000 (17:22 -0600)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 14 Dec 2017 08:26:46 +0000 (09:26 +0100)
When attempting to free a loaded VMCS02, add a WARN and avoid
freeing it (to avoid use-after-free situations).

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
Reviewed-by: Ameya More <ameya.more@oracle.com>
Reviewed-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
arch/x86/kvm/vmx.c

index d1870f3c8c699ce1c929d4c37d01e574b01c0ce6..3b5f7028541409ad4934f899d1e451e4ee264663 100644 (file)
@@ -3846,6 +3846,19 @@ static void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
        WARN_ON(loaded_vmcs->shadow_vmcs != NULL);
 }
 
+static void vmx_nested_free_vmcs02(struct vcpu_vmx *vmx)
+{
+       struct loaded_vmcs *loaded_vmcs = &vmx->nested.vmcs02;
+
+       /*
+        * Just leak the VMCS02 if the WARN triggers. Better than
+        * a use-after-free.
+        */
+       if (WARN_ON(vmx->loaded_vmcs == loaded_vmcs))
+               return;
+       free_loaded_vmcs(loaded_vmcs);
+}
+
 static void free_kvm_area(void)
 {
        int cpu;
@@ -7203,7 +7216,7 @@ out_cached_vmcs12:
        free_page((unsigned long)vmx->nested.msr_bitmap);
 
 out_msr_bitmap:
-       free_loaded_vmcs(&vmx->nested.vmcs02);
+       vmx_nested_free_vmcs02(vmx);
 
 out_vmcs02:
        return -ENOMEM;
@@ -7375,7 +7388,7 @@ static void free_nested(struct vcpu_vmx *vmx)
                vmx->nested.pi_desc = NULL;
        }
 
-       free_loaded_vmcs(&vmx->nested.vmcs02);
+       vmx_nested_free_vmcs02(vmx);
 }
 
 /* Emulate the VMXOFF instruction */