[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