From 424adbaf17a2d2d7a4a342dfaac906dee314f9b0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 27 Jan 2015 03:28:25 +0000 Subject: [PATCH] [x86] KVM security fixes svn path=/dists/sid/linux/; revision=22288 --- debian/changelog | 2 + ...reviously-incomplete-fix-for-cve-201.patch | 28 +++++++ ...kvm-x86-sysenter-emulation-is-broken.patch | 78 +++++++++++++++++++ debian/patches/series | 2 + 4 files changed, 110 insertions(+) create mode 100644 debian/patches/bugfix/x86/kvm-x86-fix-of-previously-incomplete-fix-for-cve-201.patch create mode 100644 debian/patches/bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch diff --git a/debian/changelog b/debian/changelog index 5e756a92a..4867dbef0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -17,6 +17,8 @@ linux (3.16.7-ckt4-2) UNRELEASED; urgency=medium - prefix module autoloading with "crypto-" - include crypto- module prefix in template - add missing crypto module aliases + * [x86] KVM: Fix of previously incomplete fix for CVE-2014-8480 + * [x86] KVM: SYSENTER emulation is broken (CVE-2015-0239) -- Ian Campbell Fri, 16 Jan 2015 15:14:32 +0000 diff --git a/debian/patches/bugfix/x86/kvm-x86-fix-of-previously-incomplete-fix-for-cve-201.patch b/debian/patches/bugfix/x86/kvm-x86-fix-of-previously-incomplete-fix-for-cve-201.patch new file mode 100644 index 000000000..70d9484f8 --- /dev/null +++ b/debian/patches/bugfix/x86/kvm-x86-fix-of-previously-incomplete-fix-for-cve-201.patch @@ -0,0 +1,28 @@ +From: Nadav Amit +Date: Thu, 8 Jan 2015 11:59:03 +0100 +Subject: KVM: x86: Fix of previously incomplete fix for CVE-2014-8480 +Origin: https://git.kernel.org/linus/63ea0a49ae0b145b91ff2b070c01b66fc75854b9 + +STR and SLDT with rip-relative operand can cause a host kernel oops. +Mark them as DstMem as well. + +Cc: stable@vger.linux.org +Signed-off-by: Nadav Amit +Signed-off-by: Paolo Bonzini +--- + arch/x86/kvm/emulate.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -3737,8 +3737,8 @@ static const struct opcode group5[] = { + }; + + static const struct opcode group6[] = { +- DI(Prot, sldt), +- DI(Prot, str), ++ DI(Prot | DstMem, sldt), ++ DI(Prot | DstMem, str), + II(Prot | Priv | SrcMem16, em_lldt, lldt), + II(Prot | Priv | SrcMem16, em_ltr, ltr), + N, N, N, N, diff --git a/debian/patches/bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch b/debian/patches/bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch new file mode 100644 index 000000000..3d7d7dd89 --- /dev/null +++ b/debian/patches/bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch @@ -0,0 +1,78 @@ +From: Nadav Amit +Date: Thu, 1 Jan 2015 23:11:11 +0200 +Subject: KVM: x86: SYSENTER emulation is broken +Origin: https://git.kernel.org/linus/f3747379accba8e95d70cec0eae0582c8c182050 + +SYSENTER emulation is broken in several ways: +1. It misses the case of 16-bit code segments completely (CVE-2015-0239). +2. MSR_IA32_SYSENTER_CS is checked in 64-bit mode incorrectly (bits 0 and 1 can + still be set without causing #GP). +3. MSR_IA32_SYSENTER_EIP and MSR_IA32_SYSENTER_ESP are not masked in + legacy-mode. +4. There is some unneeded code. + +Fix it. + +Cc: stable@vger.linux.org +Signed-off-by: Nadav Amit +Signed-off-by: Paolo Bonzini +[bwh: Backported to 3.16: adjust context] +--- + arch/x86/kvm/emulate.c | 27 ++++++++------------------- + 1 file changed, 8 insertions(+), 19 deletions(-) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -2302,7 +2302,7 @@ static int em_sysenter(struct x86_emulat + * Not recognized on AMD in compat mode (but is recognized in legacy + * mode). + */ +- if ((ctxt->mode == X86EMUL_MODE_PROT32) && (efer & EFER_LMA) ++ if ((ctxt->mode != X86EMUL_MODE_PROT64) && (efer & EFER_LMA) + && !vendor_intel(ctxt)) + return emulate_ud(ctxt); + +@@ -2315,25 +2315,13 @@ static int em_sysenter(struct x86_emulat + setup_syscalls_segments(ctxt, &cs, &ss); + + ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data); +- switch (ctxt->mode) { +- case X86EMUL_MODE_PROT32: +- if ((msr_data & 0xfffc) == 0x0) +- return emulate_gp(ctxt, 0); +- break; +- case X86EMUL_MODE_PROT64: +- if (msr_data == 0x0) +- return emulate_gp(ctxt, 0); +- break; +- default: +- break; +- } ++ if ((msr_data & 0xfffc) == 0x0) ++ return emulate_gp(ctxt, 0); + + ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); +- cs_sel = (u16)msr_data; +- cs_sel &= ~SELECTOR_RPL_MASK; ++ cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK; + ss_sel = cs_sel + 8; +- ss_sel &= ~SELECTOR_RPL_MASK; +- if (ctxt->mode == X86EMUL_MODE_PROT64 || (efer & EFER_LMA)) { ++ if (efer & EFER_LMA) { + cs.d = 0; + cs.l = 1; + } +@@ -2342,10 +2330,11 @@ static int em_sysenter(struct x86_emulat + ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); + + ops->get_msr(ctxt, MSR_IA32_SYSENTER_EIP, &msr_data); +- ctxt->_eip = msr_data; ++ ctxt->_eip = (efer & EFER_LMA) ? msr_data : (u32)msr_data; + + ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data); +- *reg_write(ctxt, VCPU_REGS_RSP) = msr_data; ++ *reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data : ++ (u32)msr_data; + + return X86EMUL_CONTINUE; + } diff --git a/debian/patches/series b/debian/patches/series index 1b218f2d1..e18b22475 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -492,3 +492,5 @@ bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch bugfix/all/crypto-prefix-module-autoloading-with-crypto.patch bugfix/all/crypto-include-crypto-module-prefix-in-template.patch bugfix/all/crypto-add-missing-crypto-module-aliases.patch +bugfix/x86/kvm-x86-fix-of-previously-incomplete-fix-for-cve-201.patch +bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch