public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Maxim Levitsky <mlevitsk@redhat.com>
To: kvm@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"H. Peter Anvin" <hpa@zytor.com>, Shuah Khan <shuah@kernel.org>,
	Yang Zhong <yang.zhong@intel.com>,
	Wei Wang <wei.w.wang@intel.com>,
	Colton Lewis <coltonlewis@google.com>,
	Sean Christopherson <seanjc@google.com>,
	Jim Mattson <jmattson@google.com>,
	Chenyi Qiang <chenyi.qiang@intel.com>,
	Borislav Petkov <bp@alien8.de>,
	linux-kernel@vger.kernel.org, x86@kernel.org,
	Thomas Gleixner <tglx@linutronix.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	David Matlack <dmatlack@google.com>, Peter Xu <peterx@redhat.com>,
	Maxim Levitsky <mlevitsk@redhat.com>,
	linux-kselftest@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH 4/9] KVM: x86: forcibly leave nested mode on vCPU reset
Date: Thu,  3 Nov 2022 15:57:31 +0200	[thread overview]
Message-ID: <20221103135736.42295-5-mlevitsk@redhat.com> (raw)
In-Reply-To: <20221103135736.42295-1-mlevitsk@redhat.com>

While not obivous, kvm_vcpu_reset() leaves the nested mode by clearing
'vcpu->arch.hflags' but it does so without all the required housekeeping.

On SVM,	it is possible to have a vCPU reset while in guest mode because
unlike VMX, on SVM, INIT's are not latched in SVM non root mode and in
addition to that L1 doesn't have to intercept triple fault, which should
also trigger L1's reset if happens in L2 while L1 didn't intercept it.

If one of the above conditions happen, KVM will	continue to use vmcb02 while
not having in the guest mode.

Later the IA32_EFER will be cleared which will lead to freeing of the nested
guest state which will (correctly) free the vmcb02, but since KVM still
uses it (incorrectly) this will lead to a use after free and kernel crash.

This issue is assigned CVE-2022-3344

Cc: stable@vger.kernel.org
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/x86/kvm/x86.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 316ab1d5317f92..3fd900504e683b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11694,8 +11694,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 	WARN_ON_ONCE(!init_event &&
 		     (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
 
+	/*
+	 * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
+	 * possible to INIT the vCPU while L2 is active.  Force the vCPU back
+	 * into L1 as EFER.SVME is cleared on INIT (along with all other EFER
+	 * bits), i.e. virtualization is disabled.
+	 */
+	if (is_guest_mode(vcpu))
+		kvm_leave_nested(vcpu);
+
 	kvm_lapic_reset(vcpu, init_event);
 
+	WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
 	vcpu->arch.hflags = 0;
 
 	vcpu->arch.smi_pending = 0;
-- 
2.34.3


  parent reply	other threads:[~2022-11-03 13:59 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-03 13:57 [PATCH 0/9] nSVM: Security and correctness fixes Maxim Levitsky
2022-11-03 13:57 ` [PATCH 1/9] KVM: x86: nSVM: leave nested mode on vCPU free Maxim Levitsky
2022-11-03 13:57 ` [PATCH 2/9] KVM: x86: nSVM: harden svm_free_nested against freeing vmcb02 while still in use Maxim Levitsky
2022-11-03 13:57 ` [PATCH 3/9] KVM: x86: add kvm_leave_nested Maxim Levitsky
2022-11-03 13:57 ` Maxim Levitsky [this message]
2022-11-03 13:57 ` [PATCH 5/9] KVM: selftests: move idt_entry to header Maxim Levitsky
2022-11-03 13:57 ` [PATCH 6/9] kvm: selftests: add svm nested shutdown test Maxim Levitsky
2022-11-03 13:57 ` [PATCH 7/9] KVM: x86: allow L1 to not intercept triple fault Maxim Levitsky
2022-11-03 13:57 ` [PATCH 8/9] KVM: selftests: add svm part to triple_fault_test Maxim Levitsky
2022-11-03 13:57 ` [PATCH 9/9] KVM: x86: remove exit_int_info warning in svm_handle_exit Maxim Levitsky
2022-11-03 14:06 ` [PATCH 0/9] nSVM: Security and correctness fixes Maxim Levitsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221103135736.42295-5-mlevitsk@redhat.com \
    --to=mlevitsk@redhat.com \
    --cc=bp@alien8.de \
    --cc=chenyi.qiang@intel.com \
    --cc=coltonlewis@google.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dmatlack@google.com \
    --cc=hpa@zytor.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=seanjc@google.com \
    --cc=shuah@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wei.w.wang@intel.com \
    --cc=x86@kernel.org \
    --cc=yang.zhong@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox