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

Josh Boyer jwboyer at fedoraproject.org
Wed Oct 22 19:51:53 UTC 2014


commit f3bcd32f972ed0d1ac365a6b2dce2ea5a38eba7a
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                                    |   11 +++-
 x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch |   85 ++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index c9abcdd..e565900 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -759,6 +759,9 @@ Patch26032: mnt-Prevent-pivot_root-from-creating-a-loop-in-the-m.patch
 #CVE-2014-7975 rhbz 1151108 1152025
 Patch26042: fs-Add-a-missing-permission-check-to-do_umount.patch
 
+# CVE-2014-3690 rhbz 1153322 1155372
+Patch26060: x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
+
 # END OF PATCH DEFINITIONS
 
 %endif
@@ -1460,6 +1463,9 @@ ApplyPatch mnt-Prevent-pivot_root-from-creating-a-loop-in-the-m.patch
 #CVE-2014-7975 rhbz 1151108 1152025
 ApplyPatch fs-Add-a-missing-permission-check-to-do_umount.patch
 
+# CVE-2014-3690 rhbz 1153322 1155372
+ApplyPatch x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2272,6 +2278,9 @@ fi
 # and build.
 
 %changelog
+* Wed Oct 22 2014 Josh Boyer <jwboyer at fedoraproject.org>
+- CVE-2014-3690 kvm: invalid host cr4 handling (rhbz 1153322 1155372)
+
 * Wed Oct 15 2014 Justin M. Forbes <jforbes at fedoraproject.org> - 3.14.22-100
 - Linux v3.14.22
 
@@ -2287,7 +2296,7 @@ fi
 * Mon Oct 06 2014 Justin M. Forbes <jforbes at fedoraproject.org> - 3.14.20-100
 - Linux v3.14.20
 
-* Thu Sep 17 2014 Justin M. Forbes <jforbes at fedoraproject.org> - 3.14.19-100
+* Thu Sep 18 2014 Justin M. Forbes <jforbes at fedoraproject.org> - 3.14.19-100
 - Linux v3.14.19
 
 * Mon Sep 15 2014 Josh Boyer <jwboyer at fedoraproject.org>
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..2e22528
--- /dev/null
+++ b/x86-kvm-vmx-Preserve-CR4-across-VM-entry.patch
@@ -0,0 +1,85 @@
+From 2401bcf9fb70d5577699835058e740ad18da6e24 Mon Sep 17 00:00:00 2001
+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>
+
+Conflicts:
+	arch/x86/kvm/vmx.c
+---
+ 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 392752834751..21ccec8eb01b 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -441,6 +441,7 @@ struct vcpu_vmx {
+ #endif
+ 		int           gs_ldt_reload_needed;
+ 		int           fs_reload_needed;
++		unsigned long vmcs_host_cr4;	/* May not match real cr4 */
+ 	} host_state;
+ 	struct {
+ 		int vm86_active;
+@@ -4162,11 +4163,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
+ 	/*
+@@ -7186,7 +7192,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))
+@@ -7207,6 +7213,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