]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3 .26 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 1 Oct 2008 23:06:39 +0000 (16:06 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 1 Oct 2008 23:06:39 +0000 (16:06 -0700)
queue-2.6.26/series
queue-2.6.26/x64-fpu-fix-possible-fpu-leakage-in-error-conditions.patch [new file with mode: 0644]
queue-2.6.26/x86-64-clean-up-save-restore-i387-usage.patch [new file with mode: 0644]
queue-2.6.26/x86-fix-broken-ldt-access-in-vmi.patch [new file with mode: 0644]

index 3671761f532b709fd5a81c85252ec31120c1cadf..d2427c37b2d328708310097b5d88ae943f43eda9 100644 (file)
@@ -16,3 +16,6 @@ alsa-fix-locking-in-snd_pcm_open-and-snd_rawmidi_open.patch
 alsa-remove-unneeded-power_mutex-lock-in-snd_pcm_drop.patch
 kvm-svm-fix-random-segfaults-with-npt-enabled.patch
 kvm-svm-fix-guest-global-tlb-flushes-with-npt.patch
+x86-64-clean-up-save-restore-i387-usage.patch
+x64-fpu-fix-possible-fpu-leakage-in-error-conditions.patch
+x86-fix-broken-ldt-access-in-vmi.patch
diff --git a/queue-2.6.26/x64-fpu-fix-possible-fpu-leakage-in-error-conditions.patch b/queue-2.6.26/x64-fpu-fix-possible-fpu-leakage-in-error-conditions.patch
new file mode 100644 (file)
index 0000000..2828654
--- /dev/null
@@ -0,0 +1,101 @@
+From suresh.b.siddha@intel.com  Wed Oct  1 16:03:09 2008
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+Date: Tue, 30 Sep 2008 17:56:13 -0700
+Subject: x64, fpu: fix possible FPU leakage in error conditions
+To: gregkh@suse.de, stable@kernel.org
+Cc: mingo@elte.hu, torvalds@linux-foundation.org, Suresh Siddha <suresh.b.siddha@intel.com>
+Message-ID: <20081001005707.814357000@linux-os.sc.intel.com>
+Content-Disposition: inline; filename=x64-fpu-fix-possible-fpu-leakage-in-error-conditions.patch
+
+
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+
+[Upstream commit: 6ffac1e90a17ea0aded5c581204397421eec91b6]
+
+On Thu, Jul 24, 2008 at 03:43:44PM -0700, Linus Torvalds wrote:
+> So how about this patch as a starting point? This is the RightThing(tm) to
+> do regardless, and if it then makes it easier to do some other cleanups,
+> we should do it first. What do you think?
+
+restore_fpu_checking() calls init_fpu() in error conditions.
+
+While this is wrong(as our main intention is to clear the fpu state of
+the thread), this was benign before commit 92d140e21f1 ("x86: fix taking
+DNA during 64bit sigreturn").
+
+Post commit 92d140e21f1, live FPU registers may not belong to this
+process at this error scenario.
+
+In the error condition for restore_fpu_checking() (especially during the
+64bit signal return), we are doing init_fpu(), which saves the live FPU
+register state (possibly belonging to some other process context) into
+the thread struct (through unlazy_fpu() in init_fpu()). This is wrong
+and can leak the FPU data.
+
+For the signal handler restore error condition in restore_i387(), clear
+the fpu state present in the thread struct(before ultimately sending a
+SIGSEGV for badframe).
+
+For the paranoid error condition check in math_state_restore(), send a
+SIGSEGV, if we fail to restore the state.
+
+Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/signal_64.c |   11 ++++++++++-
+ arch/x86/kernel/traps_64.c  |    9 ++++++++-
+ include/asm-x86/i387.h      |    2 --
+ 3 files changed, 18 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kernel/signal_64.c
++++ b/arch/x86/kernel/signal_64.c
+@@ -104,7 +104,16 @@ static inline int restore_i387(struct _f
+               clts();
+               task_thread_info(current)->status |= TS_USEDFPU;
+       }
+-      return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
++      err = restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
++      if (unlikely(err)) {
++              /*
++               * Encountered an error while doing the restore from the
++               * user buffer, clear the fpu state.
++               */
++              clear_fpu(tsk);
++              clear_used_math();
++      }
++      return err;
+ }
+ /*
+--- a/arch/x86/kernel/traps_64.c
++++ b/arch/x86/kernel/traps_64.c
+@@ -1141,7 +1141,14 @@ asmlinkage void math_state_restore(void)
+       }
+       clts();                 /* Allow maths ops (or we recurse) */
+-      restore_fpu_checking(&me->thread.xstate->fxsave);
++      /*
++       * Paranoid restore. send a SIGSEGV if we fail to restore the state.
++       */
++      if (unlikely(restore_fpu_checking(&me->thread.xstate->fxsave))) {
++              stts();
++              force_sig(SIGSEGV, me);
++              return;
++      }
+       task_thread_info(me)->status |= TS_USEDFPU;
+       me->fpu_counter++;
+ }
+--- a/include/asm-x86/i387.h
++++ b/include/asm-x86/i387.h
+@@ -63,8 +63,6 @@ static inline int restore_fpu_checking(s
+ #else
+                    : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
+ #endif
+-      if (unlikely(err))
+-              init_fpu(current);
+       return err;
+ }
diff --git a/queue-2.6.26/x86-64-clean-up-save-restore-i387-usage.patch b/queue-2.6.26/x86-64-clean-up-save-restore-i387-usage.patch
new file mode 100644 (file)
index 0000000..e842ac4
--- /dev/null
@@ -0,0 +1,164 @@
+From suresh.b.siddha@intel.com  Wed Oct  1 16:02:35 2008
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 30 Sep 2008 17:56:12 -0700
+Subject: x86-64: Clean up save/restore_i387() usage
+To: gregkh@suse.de, stable@kernel.org
+Cc: mingo@elte.hu, torvalds@linux-foundation.org, Suresh Siddha <suresh.b.siddha@intel.com>
+Message-ID: <20081001005707.657809000@linux-os.sc.intel.com>
+Content-Disposition: inline; filename=x86-64-clean-up-save-restore-i387-usage.patch
+
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit b30f3ae50cd03ef2ff433a5030fbf88dd8323528]
+
+Suresh Siddha wants to fix a possible FPU leakage in error conditions,
+but the fact that save/restore_i387() are inlines in a header file makes
+that harder to do than necessary.  So start off with an obvious cleanup.
+
+This just moves the x86-64 version of save/restore_i387() out of the
+header file, and moves it to the only file that it is actually used in:
+arch/x86/kernel/signal_64.c.  So exposing it in a header file was wrong
+to begin with.
+
+[ Side note: I'd like to fix up some of the games we play with the
+  32-bit version of these functions too, but that's a separate
+  matter.  The 32-bit versions are shared - under different names
+  at that! - by both the native x86-32 code and the x86-64 32-bit
+  compatibility code ]
+
+Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+---
+ arch/x86/kernel/signal_64.c |   53 +++++++++++++++++++++++++++++++++++++++++++
+ include/asm-x86/i387.h      |   54 --------------------------------------------
+ 2 files changed, 53 insertions(+), 54 deletions(-)
+
+--- a/arch/x86/kernel/signal_64.c
++++ b/arch/x86/kernel/signal_64.c
+@@ -53,6 +53,59 @@ sys_sigaltstack(const stack_t __user *us
+       return do_sigaltstack(uss, uoss, regs->sp);
+ }
++/*
++ * Signal frame handlers.
++ */
++
++static inline int save_i387(struct _fpstate __user *buf)
++{
++      struct task_struct *tsk = current;
++      int err = 0;
++
++      BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
++                      sizeof(tsk->thread.xstate->fxsave));
++
++      if ((unsigned long)buf % 16)
++              printk("save_i387: bad fpstate %p\n", buf);
++
++      if (!used_math())
++              return 0;
++      clear_used_math(); /* trigger finit */
++      if (task_thread_info(tsk)->status & TS_USEDFPU) {
++              err = save_i387_checking((struct i387_fxsave_struct __user *)
++                                       buf);
++              if (err)
++                      return err;
++              task_thread_info(tsk)->status &= ~TS_USEDFPU;
++              stts();
++      } else {
++              if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
++                                 sizeof(struct i387_fxsave_struct)))
++                      return -1;
++      }
++      return 1;
++}
++
++/*
++ * This restores directly out of user space. Exceptions are handled.
++ */
++static inline int restore_i387(struct _fpstate __user *buf)
++{
++      struct task_struct *tsk = current;
++      int err;
++
++      if (!used_math()) {
++              err = init_fpu(tsk);
++              if (err)
++                      return err;
++      }
++
++      if (!(task_thread_info(current)->status & TS_USEDFPU)) {
++              clts();
++              task_thread_info(current)->status |= TS_USEDFPU;
++      }
++      return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
++}
+ /*
+  * Do a signal return; undo the signal stack.
+--- a/include/asm-x86/i387.h
++++ b/include/asm-x86/i387.h
+@@ -138,60 +138,6 @@ static inline void __save_init_fpu(struc
+       task_thread_info(tsk)->status &= ~TS_USEDFPU;
+ }
+-/*
+- * Signal frame handlers.
+- */
+-
+-static inline int save_i387(struct _fpstate __user *buf)
+-{
+-      struct task_struct *tsk = current;
+-      int err = 0;
+-
+-      BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
+-                      sizeof(tsk->thread.xstate->fxsave));
+-
+-      if ((unsigned long)buf % 16)
+-              printk("save_i387: bad fpstate %p\n", buf);
+-
+-      if (!used_math())
+-              return 0;
+-      clear_used_math(); /* trigger finit */
+-      if (task_thread_info(tsk)->status & TS_USEDFPU) {
+-              err = save_i387_checking((struct i387_fxsave_struct __user *)
+-                                       buf);
+-              if (err)
+-                      return err;
+-              task_thread_info(tsk)->status &= ~TS_USEDFPU;
+-              stts();
+-      } else {
+-              if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
+-                                 sizeof(struct i387_fxsave_struct)))
+-                      return -1;
+-      }
+-      return 1;
+-}
+-
+-/*
+- * This restores directly out of user space. Exceptions are handled.
+- */
+-static inline int restore_i387(struct _fpstate __user *buf)
+-{
+-      struct task_struct *tsk = current;
+-      int err;
+-
+-      if (!used_math()) {
+-              err = init_fpu(tsk);
+-              if (err)
+-                      return err;
+-      }
+-
+-      if (!(task_thread_info(current)->status & TS_USEDFPU)) {
+-              clts();
+-              task_thread_info(current)->status |= TS_USEDFPU;
+-      }
+-      return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
+-}
+-
+ #else  /* CONFIG_X86_32 */
+ extern void finit(void);
diff --git a/queue-2.6.26/x86-fix-broken-ldt-access-in-vmi.patch b/queue-2.6.26/x86-fix-broken-ldt-access-in-vmi.patch
new file mode 100644 (file)
index 0000000..84f82d6
--- /dev/null
@@ -0,0 +1,41 @@
+From jejb@kernel.org  Wed Oct  1 16:03:54 2008
+From: Zachary Amsden <zach@vmware.com>
+Date: Wed, 1 Oct 2008 16:45:04 GMT
+Subject: x86: Fix broken LDT access in VMI
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810011645.m91Gj4ou017971@hera.kernel.org>
+
+From: Zachary Amsden <zach@vmware.com>
+
+commit de59985e3a623d4d5d6207f1777398ca0606ab1c upstream
+
+After investigating a JRE failure, I found this bug was introduced a
+long time ago, and had already managed to survive another bugfix which
+occurred on the same line.  The result is a total failure of the JRE due
+to LDT selectors not working properly.
+
+This one took a long time to rear up because LDT usage is not very
+common, but the bug is quite serious.  It got introduced along with
+another bug, already fixed, by 75b8bb3e56ca09a467fbbe5229bc68627f7445be
+
+Signed-off-by: Zachary Amsden <zach@vmware.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Glauber de Oliveira Costa <gcosta@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/vmi_32.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/vmi_32.c
++++ b/arch/x86/kernel/vmi_32.c
+@@ -234,7 +234,7 @@ static void vmi_write_ldt_entry(struct d
+                               const void *desc)
+ {
+       u32 *ldt_entry = (u32 *)desc;
+-      vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
++      vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
+ }
+ static void vmi_load_sp0(struct tss_struct *tss,