[kernel/f20] CVE-2014-3690 kvm: invalid host cr4 handling (rhbz 1153322 1155372)

Josh Boyer jwboyer at fedoraproject.org
Wed Oct 22 19:52:04 UTC 2014


commit 5d44dc759af4b0e6377912c53d10986b07127574
Author: Josh Boyer <jwboyer at fedoraproject.org>
Date:   Wed Oct 22 12:45:05 2014 -0400

    CVE-2014-3690 kvm: invalid host cr4 handling (rhbz 1153322 1155372)

 kernel.spec                                    |    8 +++
 x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch |   81 ++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 2be3b01..5ef015a 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -745,6 +745,9 @@ Patch26058: asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
 #rhbz 1153381
 Patch26059: Input-synaptics-gate-forcepad-support-by-DMI-check.patch
 
+# CVE-2014-3690 rhbz 1153322 1155372
+Patch26060: x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
+
 # git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
 Patch30000: kernel-arm64.patch
 
@@ -1458,6 +1461,10 @@ ApplyPatch asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
 #rhbz 1153381
 ApplyPatch Input-synaptics-gate-forcepad-support-by-DMI-check.patch
 
+# CVE-2014-3690 rhbz 1153322 1155372
+ApplyPatch x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
+
+
 %if 0%{?aarch64patches}
 ApplyPatch kernel-arm64.patch
 %ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
@@ -2277,6 +2284,7 @@ fi
 #                 ||     ||
 %changelog
 * Wed Oct 22 2014 Josh Boyer <jwboyer at fedoraproject.org>
+- CVE-2014-3690 kvm: invalid host cr4 handling (rhbz 1153322 1155372)
 - Add patch to fix synaptics forcepad issues (rhbz 1153381)
 - Add patch to fix wifi on X550VB machines (rhbz 1089731)
 
diff --git a/x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch b/x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
new file mode 100644
index 0000000..92ec436
--- /dev/null
+++ b/x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
@@ -0,0 +1,81 @@
+From: Andy Lutomirski <luto at amacapital.net>
+Date: Wed, 8 Oct 2014 09:02:13 -0700
+Subject: [PATCH] x86,kvm,vmx: Preserve CR4 across VM entry
+
+CR4 isn't constant; at least the TSD and PCE bits can vary.
+
+TBH, treating CR0 and CR3 as constant scares me a bit, too, but it looks
+like it's correct.
+
+This adds a branch and a read from cr4 to each vm entry.  Because it is
+extremely likely that consecutive entries into the same vcpu will have
+the same host cr4 value, this fixes up the vmcs instead of restoring cr4
+after the fact.  A subsequent patch will add a kernel-wide cr4 shadow,
+reducing the overhead in the common case to just two memory reads and a
+branch.
+
+Signed-off-by: Andy Lutomirski <luto at amacapital.net>
+Acked-by: Paolo Bonzini <pbonzini at redhat.com>
+Cc: stable at vger.kernel.org
+Cc: Petr Matousek <pmatouse at redhat.com>
+Cc: Gleb Natapov <gleb at kernel.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+ arch/x86/kvm/vmx.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index bfe11cf124a1..6a118fa378b5 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -453,6 +453,7 @@ struct vcpu_vmx {
+ 		int           gs_ldt_reload_needed;
+ 		int           fs_reload_needed;
+ 		u64           msr_host_bndcfgs;
++		unsigned long vmcs_host_cr4;	/* May not match real cr4 */
+ 	} host_state;
+ 	struct {
+ 		int vm86_active;
+@@ -4235,11 +4236,16 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
+ 	u32 low32, high32;
+ 	unsigned long tmpl;
+ 	struct desc_ptr dt;
++	unsigned long cr4;
+ 
+ 	vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS);  /* 22.2.3 */
+-	vmcs_writel(HOST_CR4, read_cr4());  /* 22.2.3, 22.2.5 */
+ 	vmcs_writel(HOST_CR3, read_cr3());  /* 22.2.3  FIXME: shadow tables */
+ 
++	/* Save the most likely value for this task's CR4 in the VMCS. */
++	cr4 = read_cr4();
++	vmcs_writel(HOST_CR4, cr4);			/* 22.2.3, 22.2.5 */
++	vmx->host_state.vmcs_host_cr4 = cr4;
++
+ 	vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS);  /* 22.2.4 */
+ #ifdef CONFIG_X86_64
+ 	/*
+@@ -7376,7 +7382,7 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
+ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+-	unsigned long debugctlmsr;
++	unsigned long debugctlmsr, cr4;
+ 
+ 	/* Record the guest's net vcpu time for enforced NMI injections. */
+ 	if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
+@@ -7397,6 +7403,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ 	if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
+ 		vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
+ 
++	cr4 = read_cr4();
++	if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) {
++		vmcs_writel(HOST_CR4, cr4);
++		vmx->host_state.vmcs_host_cr4 = cr4;
++	}
++
+ 	/* When single-stepping over STI and MOV SS, we must clear the
+ 	 * corresponding interruptibility bits in the guest state. Otherwise
+ 	 * vmentry fails as it then expects bit 14 (BS) in pending debug
+-- 
+1.9.3
+


More information about the scm-commits mailing list