]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Nov 2014 23:09:34 +0000 (15:09 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Nov 2014 23:09:34 +0000 (15:09 -0800)
added patches:
x86-flags-rename-x86_eflags_bit1-to-x86_eflags_fixed.patch
x86-fpu-__restore_xstate_sig-math_state_restore-needs-preempt_disable.patch
x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch
x86-reject-x32-executables-if-x32-abi-not-supported.patch
x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch

queue-3.10/series
queue-3.10/x86-flags-rename-x86_eflags_bit1-to-x86_eflags_fixed.patch [new file with mode: 0644]
queue-3.10/x86-fpu-__restore_xstate_sig-math_state_restore-needs-preempt_disable.patch [new file with mode: 0644]
queue-3.10/x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch [new file with mode: 0644]
queue-3.10/x86-reject-x32-executables-if-x32-abi-not-supported.patch [new file with mode: 0644]
queue-3.10/x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch [new file with mode: 0644]

index b34e3cabc8cea73318d793be498f9d6b19579b41..8f8a4fcd7fae0cb31cf9c860c61e6b3253b87c83 100644 (file)
@@ -14,3 +14,8 @@ ubifs-remove-mst_mutex.patch
 ubifs-fix-a-race-condition.patch
 ubifs-fix-free-log-space-calculation.patch
 vfs-fix-data-corruption-when-blocksize-pagesize-for-mmaped-data.patch
+x86-reject-x32-executables-if-x32-abi-not-supported.patch
+x86-fpu-__restore_xstate_sig-math_state_restore-needs-preempt_disable.patch
+x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch
+x86-flags-rename-x86_eflags_bit1-to-x86_eflags_fixed.patch
+x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch
diff --git a/queue-3.10/x86-flags-rename-x86_eflags_bit1-to-x86_eflags_fixed.patch b/queue-3.10/x86-flags-rename-x86_eflags_bit1-to-x86_eflags_fixed.patch
new file mode 100644 (file)
index 0000000..3f88a64
--- /dev/null
@@ -0,0 +1,95 @@
+From 1adfa76a95fe4444124a502f7cc858a39d5b8e01 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+Date: Sat, 27 Apr 2013 16:10:11 -0700
+Subject: x86, flags: Rename X86_EFLAGS_BIT1 to X86_EFLAGS_FIXED
+
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+
+commit 1adfa76a95fe4444124a502f7cc858a39d5b8e01 upstream.
+
+Bit 1 in the x86 EFLAGS is always set.  Name the macro something that
+actually tries to explain what it is all about, rather than being a
+tautology.
+
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Gleb Natapov <gleb@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Link: http://lkml.kernel.org/n/tip-f10rx5vjjm6tfnt8o1wseb3v@git.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/uapi/asm/processor-flags.h |    2 +-
+ arch/x86/kernel/entry_64.S                  |    2 +-
+ arch/x86/kernel/process_32.c                |    2 +-
+ arch/x86/kernel/process_64.c                |    2 +-
+ arch/x86/kvm/vmx.c                          |    2 +-
+ drivers/lguest/x86/core.c                   |    2 +-
+ 6 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/include/uapi/asm/processor-flags.h
++++ b/arch/x86/include/uapi/asm/processor-flags.h
+@@ -6,7 +6,7 @@
+  * EFLAGS bits
+  */
+ #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
+-#define X86_EFLAGS_BIT1       0x00000002 /* Bit 1 - always on */
++#define X86_EFLAGS_FIXED 0x00000002 /* Bit 1 - always on */
+ #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
+ #define X86_EFLAGS_AF 0x00000010 /* Auxiliary carry Flag */
+ #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -366,7 +366,7 @@ ENDPROC(native_usergs_sysret64)
+       /*CFI_REL_OFFSET        ss,0*/
+       pushq_cfi %rax /* rsp */
+       CFI_REL_OFFSET  rsp,0
+-      pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_BIT1) /* eflags - interrupts on */
++      pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED) /* eflags - interrupts on */
+       /*CFI_REL_OFFSET        rflags,0*/
+       pushq_cfi $__KERNEL_CS /* cs */
+       /*CFI_REL_OFFSET        cs,0*/
+--- a/arch/x86/kernel/process_32.c
++++ b/arch/x86/kernel/process_32.c
+@@ -147,7 +147,7 @@ int copy_thread(unsigned long clone_flag
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+-              childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
++              childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
+               p->fpu_counter = 0;
+               p->thread.io_bitmap_ptr = NULL;
+               memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -176,7 +176,7 @@ int copy_thread(unsigned long clone_flag
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+-              childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
++              childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
+               return 0;
+       }
+       *childregs = *current_pt_regs();
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -7949,7 +7949,7 @@ static void load_vmcs12_host_state(struc
+       kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->host_rsp);
+       kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->host_rip);
+-      vmx_set_rflags(vcpu, X86_EFLAGS_BIT1);
++      vmx_set_rflags(vcpu, X86_EFLAGS_FIXED);
+       /*
+        * Note that calling vmx_set_cr0 is important, even if cr0 hasn't
+        * actually changed, because it depends on the current state of
+--- a/drivers/lguest/x86/core.c
++++ b/drivers/lguest/x86/core.c
+@@ -700,7 +700,7 @@ void lguest_arch_setup_regs(struct lg_cp
+        * interrupts are enabled.  We always leave interrupts enabled while
+        * running the Guest.
+        */
+-      regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
++      regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
+       /*
+        * The "Extended Instruction Pointer" register says where the Guest is
diff --git a/queue-3.10/x86-fpu-__restore_xstate_sig-math_state_restore-needs-preempt_disable.patch b/queue-3.10/x86-fpu-__restore_xstate_sig-math_state_restore-needs-preempt_disable.patch
new file mode 100644 (file)
index 0000000..162753d
--- /dev/null
@@ -0,0 +1,38 @@
+From df24fb859a4e200d9324e2974229fbb7adf00aef Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Tue, 2 Sep 2014 19:57:17 +0200
+Subject: x86, fpu: __restore_xstate_sig()->math_state_restore() needs preempt_disable()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit df24fb859a4e200d9324e2974229fbb7adf00aef upstream.
+
+Add preempt_disable() + preempt_enable() around math_state_restore() in
+__restore_xstate_sig(). Otherwise __switch_to() after __thread_fpu_begin()
+can overwrite fpu->state we are going to restore.
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Link: http://lkml.kernel.org/r/20140902175717.GA21649@redhat.com
+Reviewed-by: Suresh Siddha <sbsiddha@gmail.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/xsave.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/xsave.c
++++ b/arch/x86/kernel/xsave.c
+@@ -400,8 +400,11 @@ int __restore_xstate_sig(void __user *bu
+                       set_used_math();
+               }
+-              if (use_eager_fpu())
++              if (use_eager_fpu()) {
++                      preempt_disable();
+                       math_state_restore();
++                      preempt_enable();
++              }
+               return err;
+       } else {
diff --git a/queue-3.10/x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch b/queue-3.10/x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch
new file mode 100644 (file)
index 0000000..02d8008
--- /dev/null
@@ -0,0 +1,118 @@
+From 66463db4fc5605d51c7bb81d009d5bf30a783a2c Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Tue, 2 Sep 2014 19:57:13 +0200
+Subject: x86, fpu: shift drop_init_fpu() from save_xstate_sig() to handle_signal()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 66463db4fc5605d51c7bb81d009d5bf30a783a2c upstream.
+
+save_xstate_sig()->drop_init_fpu() doesn't look right. setup_rt_frame()
+can fail after that, in this case the next setup_rt_frame() triggered
+by SIGSEGV won't save fpu simply because the old state was lost. This
+obviously mean that fpu won't be restored after sys_rt_sigreturn() from
+SIGSEGV handler.
+
+Shift drop_init_fpu() into !failed branch in handle_signal().
+
+Test-case (needs -O2):
+
+       #include <stdio.h>
+       #include <signal.h>
+       #include <unistd.h>
+       #include <sys/syscall.h>
+       #include <sys/mman.h>
+       #include <pthread.h>
+       #include <assert.h>
+
+       volatile double D;
+
+       void test(double d)
+       {
+               int pid = getpid();
+
+               for (D = d; D == d; ) {
+                       /* sys_tkill(pid, SIGHUP); asm to avoid save/reload
+                        * fp regs around "C" call */
+                       asm ("" : : "a"(200), "D"(pid), "S"(1));
+                       asm ("syscall" : : : "ax");
+               }
+
+               printf("ERR!!\n");
+       }
+
+       void sigh(int sig)
+       {
+       }
+
+       char altstack[4096 * 10] __attribute__((aligned(4096)));
+
+       void *tfunc(void *arg)
+       {
+               for (;;) {
+                       mprotect(altstack, sizeof(altstack), PROT_READ);
+                       mprotect(altstack, sizeof(altstack), PROT_READ|PROT_WRITE);
+               }
+       }
+
+       int main(void)
+       {
+               stack_t st = {
+                       .ss_sp = altstack,
+                       .ss_size = sizeof(altstack),
+                       .ss_flags = SS_ONSTACK,
+               };
+
+               struct sigaction sa = {
+                       .sa_handler = sigh,
+               };
+
+               pthread_t pt;
+
+               sigaction(SIGSEGV, &sa, NULL);
+               sigaltstack(&st, NULL);
+               sa.sa_flags = SA_ONSTACK;
+               sigaction(SIGHUP, &sa, NULL);
+
+               pthread_create(&pt, NULL, tfunc, NULL);
+
+               test(123.456);
+               return 0;
+       }
+
+Reported-by: Bean Anderson <bean@azulsystems.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Link: http://lkml.kernel.org/r/20140902175713.GA21646@redhat.com
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/signal.c |    5 +++++
+ arch/x86/kernel/xsave.c  |    2 --
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kernel/signal.c
++++ b/arch/x86/kernel/signal.c
+@@ -677,6 +677,11 @@ handle_signal(struct ksignal *ksig, stru
+                * handler too.
+                */
+               regs->flags &= ~X86_EFLAGS_TF;
++              /*
++               * Ensure the signal handler starts with the new fpu state.
++               */
++              if (used_math())
++                      drop_init_fpu(current);
+       }
+       signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
+ }
+--- a/arch/x86/kernel/xsave.c
++++ b/arch/x86/kernel/xsave.c
+@@ -268,8 +268,6 @@ int save_xstate_sig(void __user *buf, vo
+       if (use_fxsr() && save_xstate_epilog(buf_fx, ia32_fxstate))
+               return -1;
+-      drop_init_fpu(tsk);     /* trigger finit */
+-
+       return 0;
+ }
diff --git a/queue-3.10/x86-reject-x32-executables-if-x32-abi-not-supported.patch b/queue-3.10/x86-reject-x32-executables-if-x32-abi-not-supported.patch
new file mode 100644 (file)
index 0000000..73cf271
--- /dev/null
@@ -0,0 +1,39 @@
+From 0e6d3112a4e95d55cf6dca88f298d5f4b8f29bd1 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 7 Sep 2014 21:05:05 +0100
+Subject: x86: Reject x32 executables if x32 ABI not supported
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 0e6d3112a4e95d55cf6dca88f298d5f4b8f29bd1 upstream.
+
+It is currently possible to execve() an x32 executable on an x86_64
+kernel that has only ia32 compat enabled.  However all its syscalls
+will fail, even _exit().  This usually causes it to segfault.
+
+Change the ELF compat architecture check so that x32 executables are
+rejected if we don't support the x32 ABI.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Link: http://lkml.kernel.org/r/1410120305.6822.9.camel@decadent.org.uk
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/elf.h |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -155,8 +155,9 @@ do {                                               \
+ #define elf_check_arch(x)                     \
+       ((x)->e_machine == EM_X86_64)
+-#define compat_elf_check_arch(x)              \
+-      (elf_check_arch_ia32(x) || (x)->e_machine == EM_X86_64)
++#define compat_elf_check_arch(x)                                      \
++      (elf_check_arch_ia32(x) ||                                      \
++       (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
+ #if __USER32_DS != __USER_DS
+ # error "The following code assumes __USER32_DS == __USER_DS"
diff --git a/queue-3.10/x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch b/queue-3.10/x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch
new file mode 100644 (file)
index 0000000..dc0acf0
--- /dev/null
@@ -0,0 +1,116 @@
+From 8c7aa698baca5e8f1ba9edb68081f1e7a1abf455 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@amacapital.net>
+Date: Wed, 1 Oct 2014 11:49:04 -0700
+Subject: x86_64, entry: Filter RFLAGS.NT on entry from userspace
+
+From: Andy Lutomirski <luto@amacapital.net>
+
+commit 8c7aa698baca5e8f1ba9edb68081f1e7a1abf455 upstream.
+
+The NT flag doesn't do anything in long mode other than causing IRET
+to #GP.  Oddly, CPL3 code can still set NT using popf.
+
+Entry via hardware or software interrupt clears NT automatically, so
+the only relevant entries are fast syscalls.
+
+If user code causes kernel code to run with NT set, then there's at
+least some (small) chance that it could cause trouble.  For example,
+user code could cause a call to EFI code with NT set, and who knows
+what would happen?  Apparently some games on Wine sometimes do
+this (!), and, if an IRET return happens, they will segfault.  That
+segfault cannot be handled, because signal delivery fails, too.
+
+This patch programs the CPU to clear NT on entry via SYSCALL (both
+32-bit and 64-bit, by my reading of the AMD APM), and it clears NT
+in software on entry via SYSENTER.
+
+To save a few cycles, this borrows a trick from Jan Beulich in Xen:
+it checks whether NT is set before trying to clear it.  As a result,
+it seems to have very little effect on SYSENTER performance on my
+machine.
+
+There's another minor bug fix in here: it looks like the CFI
+annotations were wrong if CONFIG_AUDITSYSCALL=n.
+
+Testers beware: on Xen, SYSENTER with NT set turns into a GPF.
+
+I haven't touched anything on 32-bit kernels.
+
+The syscall mask change comes from a variant of this patch by Anish
+Bhatt.
+
+Note to stable maintainers: there is no known security issue here.
+A misguided program can set NT and cause the kernel to try and fail
+to deliver SIGSEGV, crashing the program.  This patch fixes Far Cry
+on Wine: https://bugs.winehq.org/show_bug.cgi?id=33275
+
+Reported-by: Anish Bhatt <anish@chelsio.com>
+Signed-off-by: Andy Lutomirski <luto@amacapital.net>
+Link: http://lkml.kernel.org/r/395749a5d39a29bd3e4b35899cf3a3c1340e5595.1412189265.git.luto@amacapital.net
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/ia32/ia32entry.S    |   18 +++++++++++++++++-
+ arch/x86/kernel/cpu/common.c |    2 +-
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -151,6 +151,16 @@ ENTRY(ia32_sysenter_target)
+ 1:    movl    (%rbp),%ebp
+       _ASM_EXTABLE(1b,ia32_badarg)
+       ASM_CLAC
++
++      /*
++       * Sysenter doesn't filter flags, so we need to clear NT
++       * ourselves.  To save a few cycles, we can check whether
++       * NT was set instead of doing an unconditional popfq.
++       */
++      testl $X86_EFLAGS_NT,EFLAGS(%rsp)       /* saved EFLAGS match cpu */
++      jnz sysenter_fix_flags
++sysenter_flags_fixed:
++
+       orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+       testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+       CFI_REMEMBER_STATE
+@@ -184,6 +194,8 @@ sysexit_from_sys_call:
+       TRACE_IRQS_ON
+       ENABLE_INTERRUPTS_SYSEXIT32
++      CFI_RESTORE_STATE
++
+ #ifdef CONFIG_AUDITSYSCALL
+       .macro auditsys_entry_common
+       movl %esi,%r9d                  /* 6th arg: 4th syscall arg */
+@@ -226,7 +238,6 @@ sysexit_from_sys_call:
+       .endm
+ sysenter_auditsys:
+-      CFI_RESTORE_STATE
+       auditsys_entry_common
+       movl %ebp,%r9d                  /* reload 6th syscall arg */
+       jmp sysenter_dispatch
+@@ -235,6 +246,11 @@ sysexit_audit:
+       auditsys_exit sysexit_from_sys_call
+ #endif
++sysenter_fix_flags:
++      pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)
++      popfq_cfi
++      jmp sysenter_flags_fixed
++
+ sysenter_tracesys:
+ #ifdef CONFIG_AUDITSYSCALL
+       testl   $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1134,7 +1134,7 @@ void syscall_init(void)
+       /* Flags to clear on syscall */
+       wrmsrl(MSR_SYSCALL_MASK,
+              X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|
+-             X86_EFLAGS_IOPL|X86_EFLAGS_AC);
++             X86_EFLAGS_IOPL|X86_EFLAGS_AC|X86_EFLAGS_NT);
+ }
+ /*