diff --git a/kernel.spec b/kernel.spec index c9abcdd96..e565900e4 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 +- CVE-2014-3690 kvm: invalid host cr4 handling (rhbz 1153322 1155372) + * Wed Oct 15 2014 Justin M. Forbes - 3.14.22-100 - Linux v3.14.22 @@ -2287,7 +2296,7 @@ fi * Mon Oct 06 2014 Justin M. Forbes - 3.14.20-100 - Linux v3.14.20 -* Thu Sep 17 2014 Justin M. Forbes - 3.14.19-100 +* Thu Sep 18 2014 Justin M. Forbes - 3.14.19-100 - Linux v3.14.19 * Mon Sep 15 2014 Josh Boyer 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 000000000..2e2252880 --- /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 +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 +Acked-by: Paolo Bonzini +Cc: stable@vger.kernel.org +Cc: Petr Matousek +Cc: Gleb Natapov +Signed-off-by: Linus Torvalds + +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 +