From: Julian Stecklina <julian.stecklina@cyberus-technology.de>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Prescher <thomas.prescher@cyberus-technology.de>,
Julian Stecklina <julian.stecklina@cyberus-technology.de>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/2] KVM: nVMX: fix CR4_READ_SHADOW when L0 updates CR4 during a signal
Date: Tue, 16 Apr 2024 14:35:56 +0200 [thread overview]
Message-ID: <20240416123558.212040-1-julian.stecklina@cyberus-technology.de> (raw)
From: Thomas Prescher <thomas.prescher@cyberus-technology.de>
This issue occurs when the kernel is interrupted by a signal while
running a L2 guest. If the signal is meant to be delivered to the L0
VMM, and L0 updates CR4 for L1, i.e. when the VMM sets
KVM_SYNC_X86_SREGS in kvm_run->kvm_dirty_regs, the kernel programs an
incorrect read shadow value for L2's CR4.
The result is that the guest can read a value for CR4 where bits from
L1 have leaked into L2.
We found this issue by running uXen [1] as L2 in VirtualBox/KVM [2].
The issue can also easily be reproduced in Qemu/KVM if we force a sreg
sync on each call to KVM_RUN [3]. The issue can also be reproduced by
running a L2 Windows 10. In the Windows case, CR4.VMXE leaks from L1
to L2 causing the OS to blue-screen with a kernel thread exception
during TLB invalidation where the following code sequence triggers the
issue:
mov rax, cr4 <--- L2 reads CR4 with contents from L1
mov rcx, cr4
btc 0x7, rax <--- L2 toggles CR4.PGE
mov cr4, rax <--- #GP because L2 writes CR4 with reserved bits set
mov cr4, rcx
The existing code seems to fixup CR4_READ_SHADOW after calling
vmx_set_cr4 except in __set_sregs_common. While we could fix it there
as well, it's easier to just handle it centrally.
There might be a similar issue with CR0.
[1] https://github.com/OpenXT/uxen
[2] https://github.com/cyberus-technology/virtualbox-kvm
[3] https://github.com/tpressure/qemu/commit/d64c9d5e76f3f3b747bea7653d677bd61e13aafe
Signed-off-by: Julian Stecklina <julian.stecklina@cyberus-technology.de>
Signed-off-by: Thomas Prescher <thomas.prescher@cyberus-technology.de>
---
arch/x86/kvm/vmx/vmx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 6780313914f8..0d4af00245f3 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -3474,7 +3474,11 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE);
}
- vmcs_writel(CR4_READ_SHADOW, cr4);
+ if (is_guest_mode(vcpu))
+ vmcs_writel(CR4_READ_SHADOW, nested_read_cr4(get_vmcs12(vcpu)));
+ else
+ vmcs_writel(CR4_READ_SHADOW, cr4);
+
vmcs_writel(GUEST_CR4, hw_cr4);
if ((cr4 ^ old_cr4) & (X86_CR4_OSXSAVE | X86_CR4_PKE))
--
2.43.2
next reply other threads:[~2024-04-16 12:36 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-16 12:35 Julian Stecklina [this message]
2024-04-16 12:35 ` [PATCH 2/2] KVM: nVMX: remove unnecessary CR4_READ_SHADOW write Julian Stecklina
2024-04-16 14:35 ` [PATCH 1/2] KVM: nVMX: fix CR4_READ_SHADOW when L0 updates CR4 during a signal Sean Christopherson
2024-04-16 15:08 ` Thomas Prescher
2024-04-16 15:17 ` Sean Christopherson
2024-04-16 17:31 ` Thomas Prescher
2024-04-16 18:07 ` Sean Christopherson
2024-04-17 13:05 ` Thomas Prescher
2024-04-17 16:11 ` Sean Christopherson
2024-04-17 16:28 ` Sean Christopherson
2024-04-18 13:48 ` Thomas Prescher
2024-04-18 18:28 ` Sean Christopherson
2024-05-08 13:27 ` Thomas Prescher
2024-04-18 13:46 ` Thomas Prescher
2024-04-18 18:36 ` Sean Christopherson
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=20240416123558.212040-1-julian.stecklina@cyberus-technology.de \
--to=julian.stecklina@cyberus-technology.de \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=thomas.prescher@cyberus-technology.de \
--cc=x86@kernel.org \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).