]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Jan 2015 22:24:04 +0000 (14:24 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Jan 2015 22:24:04 +0000 (14:24 -0800)
added patches:
kvm-x86-fix-of-previously-incomplete-fix-for-cve-2014-8480.patch
kvm-x86-sysenter-emulation-is-broken.patch
x86-apic-re-enable-pci_msi-support-for-non-smp-x86_32.patch
x86-tls-interpret-an-all-zero-struct-user_desc-as-no-segment.patch
x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch

queue-3.18/kvm-x86-fix-of-previously-incomplete-fix-for-cve-2014-8480.patch [new file with mode: 0644]
queue-3.18/kvm-x86-sysenter-emulation-is-broken.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/x86-apic-re-enable-pci_msi-support-for-non-smp-x86_32.patch [new file with mode: 0644]
queue-3.18/x86-tls-interpret-an-all-zero-struct-user_desc-as-no-segment.patch [new file with mode: 0644]
queue-3.18/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch [new file with mode: 0644]

diff --git a/queue-3.18/kvm-x86-fix-of-previously-incomplete-fix-for-cve-2014-8480.patch b/queue-3.18/kvm-x86-fix-of-previously-incomplete-fix-for-cve-2014-8480.patch
new file mode 100644 (file)
index 0000000..4d07b97
--- /dev/null
@@ -0,0 +1,33 @@
+From 63ea0a49ae0b145b91ff2b070c01b66fc75854b9 Mon Sep 17 00:00:00 2001
+From: Nadav Amit <nadav.amit@gmail.com>
+Date: Thu, 8 Jan 2015 11:59:03 +0100
+Subject: KVM: x86: Fix of previously incomplete fix for CVE-2014-8480
+
+From: Nadav Amit <nadav.amit@gmail.com>
+
+commit 63ea0a49ae0b145b91ff2b070c01b66fc75854b9 upstream.
+
+STR and SLDT with rip-relative operand can cause a host kernel oops.
+Mark them as DstMem as well.
+
+Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -3777,8 +3777,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/queue-3.18/kvm-x86-sysenter-emulation-is-broken.patch b/queue-3.18/kvm-x86-sysenter-emulation-is-broken.patch
new file mode 100644 (file)
index 0000000..daf8124
--- /dev/null
@@ -0,0 +1,82 @@
+From f3747379accba8e95d70cec0eae0582c8c182050 Mon Sep 17 00:00:00 2001
+From: Nadav Amit <namit@cs.technion.ac.il>
+Date: Thu, 1 Jan 2015 23:11:11 +0200
+Subject: KVM: x86: SYSENTER emulation is broken
+
+From: Nadav Amit <namit@cs.technion.ac.il>
+
+commit f3747379accba8e95d70cec0eae0582c8c182050 upstream.
+
+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.
+
+Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -2345,7 +2345,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);
+@@ -2358,25 +2358,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);
+-      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;
+       }
+@@ -2385,10 +2373,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;
+ }
index 2e6acc5a3ef9b391dfa2516469e632e98d5e38cd..9cf63dbc3319599416f327656d5d789bc372946f 100644 (file)
@@ -39,3 +39,8 @@ clocksource-exynos_mct-fix-bitmask-regression-for-exynos4_mct_write.patch
 x86-hyperv-mark-the-hyper-v-clocksource-as-being-continuous.patch
 x86-tsc-change-fast-tsc-calibration-failed-from-error-to-info.patch
 x86-boot-skip-relocs-when-load-address-unchanged.patch
+kvm-x86-sysenter-emulation-is-broken.patch
+kvm-x86-fix-of-previously-incomplete-fix-for-cve-2014-8480.patch
+x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch
+x86-tls-interpret-an-all-zero-struct-user_desc-as-no-segment.patch
+x86-apic-re-enable-pci_msi-support-for-non-smp-x86_32.patch
diff --git a/queue-3.18/x86-apic-re-enable-pci_msi-support-for-non-smp-x86_32.patch b/queue-3.18/x86-apic-re-enable-pci_msi-support-for-non-smp-x86_32.patch
new file mode 100644 (file)
index 0000000..f048456
--- /dev/null
@@ -0,0 +1,58 @@
+From 38a1dfda8e77d7ba74c94d06d8bc41ba98a4bc8c Mon Sep 17 00:00:00 2001
+From: Bryan O'Donoghue <pure.logic@nexus-software.ie>
+Date: Thu, 22 Jan 2015 22:58:49 +0000
+Subject: x86/apic: Re-enable PCI_MSI support for non-SMP X86_32
+
+From: Bryan O'Donoghue <pure.logic@nexus-software.ie>
+
+commit 38a1dfda8e77d7ba74c94d06d8bc41ba98a4bc8c upstream.
+
+Commit 0dbc6078c06bc0 ('x86, build, pci: Fix PCI_MSI build on !SMP')
+introduced the dependency that X86_UP_APIC is only available when
+PCI_MSI is false. This effectively prevents PCI_MSI support on 32bit
+UP systems because it disables both APIC and IO-APIC. But APIC support
+is architecturally required for PCI_MSI.
+
+The intention of the patch was to enforce APIC support when PCI_MSI is
+enabled, but failed to do so.
+
+Remove the !PCI_MSI dependency from X86_UP_APIC and enforce
+X86_UP_APIC when PCI_MSI support is enabled on 32bit UP systems.
+
+[ tglx: Massaged changelog ]
+
+Fixes 0dbc6078c06bc0 'x86, build, pci: Fix PCI_MSI build on !SMP'
+Signed-off-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Link: http://lkml.kernel.org/r/1421967529-9037-1-git-send-email-pure.logic@nexus-software.ie
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/Kconfig |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -856,7 +856,7 @@ source "kernel/Kconfig.preempt"
+ config X86_UP_APIC
+       bool "Local APIC support on uniprocessors"
+-      depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI
++      depends on X86_32 && !SMP && !X86_32_NON_STANDARD
+       ---help---
+         A local APIC (Advanced Programmable Interrupt Controller) is an
+         integrated interrupt controller in the CPU. If you have a single-CPU
+@@ -867,6 +867,10 @@ config X86_UP_APIC
+         performance counters), and the NMI watchdog which detects hard
+         lockups.
++config X86_UP_APIC_MSI
++      def_bool y
++      select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI
++
+ config X86_UP_IOAPIC
+       bool "IO-APIC support on uniprocessors"
+       depends on X86_UP_APIC
diff --git a/queue-3.18/x86-tls-interpret-an-all-zero-struct-user_desc-as-no-segment.patch b/queue-3.18/x86-tls-interpret-an-all-zero-struct-user_desc-as-no-segment.patch
new file mode 100644 (file)
index 0000000..64c5477
--- /dev/null
@@ -0,0 +1,113 @@
+From 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@amacapital.net>
+Date: Thu, 22 Jan 2015 11:27:59 -0800
+Subject: x86, tls: Interpret an all-zero struct user_desc as "no segment"
+
+From: Andy Lutomirski <luto@amacapital.net>
+
+commit 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 upstream.
+
+The Witcher 2 did something like this to allocate a TLS segment index:
+
+        struct user_desc u_info;
+        bzero(&u_info, sizeof(u_info));
+        u_info.entry_number = (uint32_t)-1;
+
+        syscall(SYS_set_thread_area, &u_info);
+
+Strictly speaking, this code was never correct.  It should have set
+read_exec_only and seg_not_present to 1 to indicate that it wanted
+to find a free slot without putting anything there, or it should
+have put something sensible in the TLS slot if it wanted to allocate
+a TLS entry for real.  The actual effect of this code was to
+allocate a bogus segment that could be used to exploit espfix.
+
+The set_thread_area hardening patches changed the behavior, causing
+set_thread_area to return -EINVAL and crashing the game.
+
+This changes set_thread_area to interpret this as a request to find
+a free slot and to leave it empty, which isn't *quite* what the game
+expects but should be close enough to keep it working.  In
+particular, using the code above to allocate two segments will
+allocate the same segment both times.
+
+According to FrostbittenKing on Github, this fixes The Witcher 2.
+
+If this somehow still causes problems, we could instead allocate
+a limit==0 32-bit data segment, but that seems rather ugly to me.
+
+Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix
+Signed-off-by: Andy Lutomirski <luto@amacapital.net>
+Cc: torvalds@linux-foundation.org
+Link: http://lkml.kernel.org/r/0cb251abe1ff0958b8e468a9a9a905b80ae3a746.1421954363.git.luto@amacapital.net
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/desc.h |   13 +++++++++++++
+ arch/x86/kernel/tls.c       |   25 +++++++++++++++++++++++--
+ 2 files changed, 36 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/desc.h
++++ b/arch/x86/include/asm/desc.h
+@@ -262,6 +262,19 @@ static inline void native_load_tls(struc
+        (info)->seg_not_present        == 1    &&      \
+        (info)->useable                == 0)
++/* Lots of programs expect an all-zero user_desc to mean "no segment at all". */
++static inline bool LDT_zero(const struct user_desc *info)
++{
++      return (info->base_addr         == 0 &&
++              info->limit             == 0 &&
++              info->contents          == 0 &&
++              info->read_exec_only    == 0 &&
++              info->seg_32bit         == 0 &&
++              info->limit_in_pages    == 0 &&
++              info->seg_not_present   == 0 &&
++              info->useable           == 0);
++}
++
+ static inline void clear_LDT(void)
+ {
+       set_ldt(NULL, 0);
+--- a/arch/x86/kernel/tls.c
++++ b/arch/x86/kernel/tls.c
+@@ -29,7 +29,28 @@ static int get_free_idx(void)
+ static bool tls_desc_okay(const struct user_desc *info)
+ {
+-      if (LDT_empty(info))
++      /*
++       * For historical reasons (i.e. no one ever documented how any
++       * of the segmentation APIs work), user programs can and do
++       * assume that a struct user_desc that's all zeros except for
++       * entry_number means "no segment at all".  This never actually
++       * worked.  In fact, up to Linux 3.19, a struct user_desc like
++       * this would create a 16-bit read-write segment with base and
++       * limit both equal to zero.
++       *
++       * That was close enough to "no segment at all" until we
++       * hardened this function to disallow 16-bit TLS segments.  Fix
++       * it up by interpreting these zeroed segments the way that they
++       * were almost certainly intended to be interpreted.
++       *
++       * The correct way to ask for "no segment at all" is to specify
++       * a user_desc that satisfies LDT_empty.  To keep everything
++       * working, we accept both.
++       *
++       * Note that there's a similar kludge in modify_ldt -- look at
++       * the distinction between modes 1 and 0x11.
++       */
++      if (LDT_empty(info) || LDT_zero(info))
+               return true;
+       /*
+@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_str
+       cpu = get_cpu();
+       while (n-- > 0) {
+-              if (LDT_empty(info))
++              if (LDT_empty(info) || LDT_zero(info))
+                       desc->a = desc->b = 0;
+               else
+                       fill_ldt(desc, info);
diff --git a/queue-3.18/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch b/queue-3.18/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch
new file mode 100644 (file)
index 0000000..9cc6f6a
--- /dev/null
@@ -0,0 +1,52 @@
+From e30ab185c490e9a9381385529e0fd32f0a399495 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@amacapital.net>
+Date: Thu, 22 Jan 2015 11:27:58 -0800
+Subject: x86, tls, ldt: Stop checking lm in LDT_empty
+
+From: Andy Lutomirski <luto@amacapital.net>
+
+commit e30ab185c490e9a9381385529e0fd32f0a399495 upstream.
+
+32-bit programs don't have an lm bit in their ABI, so they can't
+reliably cause LDT_empty to return true without resorting to memset.
+They shouldn't need to do this.
+
+This should fix a longstanding, if minor, issue in all 64-bit kernels
+as well as a potential regression in the TLS hardening code.
+
+Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix
+Signed-off-by: Andy Lutomirski <luto@amacapital.net>
+Cc: torvalds@linux-foundation.org
+Link: http://lkml.kernel.org/r/72a059de55e86ad5e2935c80aa91880ddf19d07c.1421954363.git.luto@amacapital.net
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/desc.h |    9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/arch/x86/include/asm/desc.h
++++ b/arch/x86/include/asm/desc.h
+@@ -251,7 +251,8 @@ static inline void native_load_tls(struc
+               gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
+ }
+-#define _LDT_empty(info)                              \
++/* This intentionally ignores lm, since 32-bit apps don't have that field. */
++#define LDT_empty(info)                                       \
+       ((info)->base_addr              == 0    &&      \
+        (info)->limit                  == 0    &&      \
+        (info)->contents               == 0    &&      \
+@@ -261,12 +262,6 @@ static inline void native_load_tls(struc
+        (info)->seg_not_present        == 1    &&      \
+        (info)->useable                == 0)
+-#ifdef CONFIG_X86_64
+-#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0))
+-#else
+-#define LDT_empty(info) (_LDT_empty(info))
+-#endif
+-
+ static inline void clear_LDT(void)
+ {
+       set_ldt(NULL, 0);