KVM: nVMX: Add a WARN for freeing a loaded VMCS02

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/276c796cfef5bdaf9aae055f520b8857eaa3fa19
Commit:     276c796cfef5bdaf9aae055f520b8857eaa3fa19
Parent:     00647b44944a2f7212ac2c3825a465153d6e438f
Refname:    refs/heads/master
Author:     Mark Kanda <[email protected]>
AuthorDate: Mon Nov 27 17:22:26 2017 -0600
Committer:  Paolo Bonzini <[email protected]>
CommitDate: Thu Dec 14 09:26:46 2017 +0100

    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 <[email protected]>
    Signed-off-by: Mark Kanda <[email protected]>
    Reviewed-by: Ameya More <[email protected]>
    Reviewed-by: Krish Sadhukhan <[email protected]>
    Reviewed-by: David Hildenbrand <[email protected]>
    Reviewed-by: Paolo Bonzini <[email protected]>
    Signed-off-by: Radim Krčmář <[email protected]>
---
 arch/x86/kvm/vmx.c | 17 +++++++++++++++--
 1 file 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 */
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.