summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kanda <mark.kanda@oracle.com>2017-11-28 02:22:26 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2017-12-14 11:26:46 +0300
commit276c796cfef5bdaf9aae055f520b8857eaa3fa19 (patch)
tree1fe49210cebbd8903a7f41e02cfc94f5c03b8663
parent00647b44944a2f7212ac2c3825a465153d6e438f (diff)
downloadlinux-276c796cfef5bdaf9aae055f520b8857eaa3fa19.tar.xz
KVM: nVMX: Add a WARN for freeing a loaded VMCS02
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>
-rw-r--r--arch/x86/kvm/vmx.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d1870f3c8c69..3b5f70285414 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -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 */