mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Linux 2.6.16.9
@ 2006-04-19  7:05 Greg KH
  2006-04-19  7:06 ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2006-04-19  7:05 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: torvalds

We (the -stable team) are announcing the release of the 2.6.16.9 kernel.

The diffstat and short summary of the fixes are below.

I'll also be replying to this message with a copy of the patch between
2.6.16.8 and 2.6.16.9, as it is small enough to do so.

The updated 2.6.16.y git tree can be found at:
 	rsync://rsync.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git
and can be browsed at the normal kernel.org git web browser:
	www.kernel.org/git/

thanks,

greg k-h

--------

 Makefile                        |    2 +-
 arch/i386/kernel/cpu/amd.c      |    2 ++
 arch/x86_64/kernel/process.c    |    8 ++++++--
 arch/x86_64/kernel/setup.c      |    4 ++++
 include/asm-i386/cpufeature.h   |    1 +
 include/asm-i386/i387.h         |   30 ++++++++++++++++++++++++++----
 include/asm-x86_64/cpufeature.h |    1 +
 include/asm-x86_64/i387.h       |   20 +++++++++++++++++++-
 8 files changed, 60 insertions(+), 8 deletions(-)

Summary of changes from v2.6.16.8 to v2.6.16.9
==============================================

Andi Kleen:
      i386/x86-64: Fix x87 information leak between processes (CVE-2006-1056)

Greg Kroah-Hartman:
      Linux 2.6.16.9


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Linux 2.6.16.9
  2006-04-19  7:05 Linux 2.6.16.9 Greg KH
@ 2006-04-19  7:06 ` Greg KH
  2006-04-19  7:54   ` Denis Vlasenko
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2006-04-19  7:06 UTC (permalink / raw)
  To: linux-kernel; +Cc: stable, torvalds

diff --git a/Makefile b/Makefile
index 6346bb6..5696ad2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 16
-EXTRAVERSION = .8
+EXTRAVERSION = .9
 NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 0810f81..d2d50cb 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -207,6 +207,8 @@ #define CBAR_KEY	(0X000000CB)
 		set_bit(X86_FEATURE_K7, c->x86_capability); 
 		break;
 	}
+	if (c->x86 >= 6)
+		set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
 
 	display_cacheinfo(c);
 
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 22a05de..818ab9e 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -527,8 +527,6 @@ __switch_to(struct task_struct *prev_p, 
 	int cpu = smp_processor_id();  
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
-	unlazy_fpu(prev_p);
-
 	/*
 	 * Reload esp0, LDT and the page table pointer:
 	 */
@@ -591,6 +589,12 @@ __switch_to(struct task_struct *prev_p, 
 	prev->userrsp = read_pda(oldrsp); 
 	write_pda(oldrsp, next->userrsp); 
 	write_pda(pcurrent, next_p); 
+
+ 	/* This must be here to ensure both math_state_restore() and
+	   kernel_fpu_begin() work consistently.
+	   And the AMD workaround requires it to be after DS reload. */
+	unlazy_fpu(prev_p);
+
 	write_pda(kernelstack,
 		  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index aa55e3c..a4a0bb5 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -909,6 +909,10 @@ #endif
 	if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
 		set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
 
+	/* Enable workaround for FXSAVE leak */
+	if (c->x86 >= 6)
+		set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
+
 	r = get_model_name(c);
 	if (!r) { 
 		switch (c->x86) { 
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index c4ec2a4..9d15eec 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -70,6 +70,7 @@ #define X86_FEATURE_K7		(3*32+ 5) /* Ath
 #define X86_FEATURE_P3		(3*32+ 6) /* P3 */
 #define X86_FEATURE_P4		(3*32+ 7) /* P4 */
 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
+#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 152d0ba..7b1f011 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -13,6 +13,7 @@ #define __ASM_I386_I387_H
 
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/kernel_stat.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
@@ -38,17 +39,38 @@ #define restore_fpu(tsk)			\
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
 
+/* We need a safe address that is cheap to find and that is already
+   in L1 during context switch. The best choices are unfortunately
+   different for UP and SMP */
+#ifdef CONFIG_SMP
+#define safe_address (__per_cpu_offset[0])
+#else
+#define safe_address (kstat_cpu(0).cpustat.user)
+#endif
+
 /*
  * These must be called with preempt disabled
  */
 static inline void __save_init_fpu( struct task_struct *tsk )
 {
+	/* Use more nops than strictly needed in case the compiler
+	   varies code */
 	alternative_input(
-		"fnsave %1 ; fwait ;" GENERIC_NOP2,
-		"fxsave %1 ; fnclex",
+		"fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
+		"fxsave %[fx]\n"
+		"bt $7,%[fsw] ; jc 1f ; fnclex\n1:",
 		X86_FEATURE_FXSR,
-		"m" (tsk->thread.i387.fxsave)
-		:"memory");
+		[fx] "m" (tsk->thread.i387.fxsave),
+		[fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
+	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+	   is pending.  Clear the x87 state here by setting it to fixed
+   	   values. __per_cpu_offset[0] is a random variable that should be in L1 */
+	alternative_input(
+		GENERIC_NOP8 GENERIC_NOP2,
+		"emms\n\t"	  	/* clear stack tags */
+		"fildl %[addr]", 	/* set F?P to defined value */
+		X86_FEATURE_FXSAVE_LEAK,
+		[addr] "m" (safe_address));
 	task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
index 76bb619..662964b 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86_64/cpufeature.h
@@ -64,6 +64,7 @@ #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3
 #define X86_FEATURE_REP_GOOD	(3*32+ 4) /* rep microcode works well on this CPU */
 #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
 #define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
+#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
index 876eb9a..cba8a3b 100644
--- a/include/asm-x86_64/i387.h
+++ b/include/asm-x86_64/i387.h
@@ -72,6 +72,23 @@ #define set_fpu_cwd(t,val) ((t)->thread.
 #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
 #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
 
+#define X87_FSW_ES (1 << 7)	/* Exception Summary */
+
+/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
+   is pending. Clear the x87 state here by setting it to fixed
+   values. The kernel data segment can be sometimes 0 and sometimes
+   new user value. Both should be ok.
+   Use the PDA as safe address because it should be already in L1. */
+static inline void clear_fpu_state(struct i387_fxsave_struct *fx)
+{
+	if (unlikely(fx->swd & X87_FSW_ES))
+		 asm volatile("fnclex");
+	alternative_input(ASM_NOP8 ASM_NOP2,
+	     	     "    emms\n"		/* clear stack tags */
+	     	     "    fildl %%gs:0",	/* load to clear state */
+		     X86_FEATURE_FXSAVE_LEAK);
+}
+
 static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) 
 { 
 	int err;
@@ -119,6 +136,7 @@ #else
 #endif
 	if (unlikely(err))
 		__clear_user(fx, sizeof(struct i387_fxsave_struct));
+	/* No need to clear here because the caller clears USED_MATH */
 	return err;
 } 
 
@@ -149,7 +167,7 @@ #else
 				"i" (offsetof(__typeof__(*tsk),
 					      thread.i387.fxsave)));
 #endif
-	__asm__ __volatile__("fnclex");
+	clear_fpu_state(&tsk->thread.i387.fxsave);
 }
 
 static inline void kernel_fpu_begin(void)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Linux 2.6.16.9
  2006-04-19  7:06 ` Greg KH
@ 2006-04-19  7:54   ` Denis Vlasenko
  0 siblings, 0 replies; 4+ messages in thread
From: Denis Vlasenko @ 2006-04-19  7:54 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, stable, torvalds

On Wednesday 19 April 2006 10:06, Greg KH wrote:
> diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
> index c4ec2a4..9d15eec 100644
> --- a/include/asm-i386/cpufeature.h
> +++ b/include/asm-i386/cpufeature.h
> @@ -70,6 +70,7 @@ #define X86_FEATURE_K7		(3*32+ 5) /* Ath
>  #define X86_FEATURE_P3		(3*32+ 6) /* P3 */
>  #define X86_FEATURE_P4		(3*32+ 7) /* P4 */
>  #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
> +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */

Most likely "FOP/FIP/FDP"...
--
vda

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: Linux 2.6.16.9
@ 2006-04-19 22:59 Brunner, Richard
  0 siblings, 0 replies; 4+ messages in thread
From: Brunner, Richard @ 2006-04-19 22:59 UTC (permalink / raw)
  To: linux-kernel


		AMD Background/Response
		Rich Brunner, AMD Fellow

AMD appreciates  the security community  contacting us about
this issue and giving us a chance to respond. Many thanks to
Jan Beulich and Andi Kleen for first  alerting us to the  
concern around this issue and trying out several solutions.


Introduction
============
To summarize the issue from AMD's perspective, AMD documents
the  operation of  the  FXSAVE and  FXRSTOR instructions  as
follows  in  the  "AMD64  Architecture  Programmer's  Manual
Volume 5:  64-Bit Media and  x87 Floating-Point Instructions
Rev 3.06":

(http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26569.pdf)

  + FXRSTOR (pg 350):

    "FXRSTOR does  not restore the x87  error pointers (last
     instruction  pointer,  last   data  pointer,  and  last
     opcode), except  in the relatively rare  cases in which
     the exception  summary (ES) bit in the  x87 status word
     is set to 1,  indicating that an unmasked x87 exception
     has occurred."

  + FXSAVE (pg 352):

    "FXSAVE does  not save  the x87 pointer  registers (last
     instruction  pointer,  last   data  pointer,  and  last
     opcode), except  in the relatively rare  cases in which
     the exception  summary (ES) bit in the  x87 status word
     is set to 1,  indicating that an unmasked x87 exception
     has occurred."

AMD purposely designed the  implementation of the FXSAVE and
FXRSTOR  instructions in the  above manner  to significantly
improve the  performance of context-switching.   AMD did not
want to  penalize the performance of  these instructions for
all operating systems for  the relatively rare case when the
exception summary  bit was set  or the unlikely case  of the
x87  exceptions pointers being  successfully exploited  in a
real  customer  environment.    Instead,  AMD  designed  the
instructions to optimize performance for the common case.

As a  result of the operation  of FXSAVE and  FXRSTOR, it is
theoretically possible  for one process  (reader) to observe
the  x87  exception  pointers  of another  process  (writer)
provided that:

  + no  other x87 instructions are executed  that affect the
    x87 exception  pointers between  the time the  writer is
    swapped out and the reader is swapped in; and

  + the  reader does not  have a pending x87  exception when
    swapped back in; and

  + the   reader  does    not  issue  any   non-control  x87
    instructions when  swapped back in  before examining x87
    exception pointers.

Operating  systems can employ one of several simple software 
methods to remove the possibility of exploitation as 
described  below. In some cases, these methods may actually 
*improve* the performance of an operating-system's 
context-switching code.


Software Methods
================
There  are  a number  of  methods,  "Clear Sequences",  that
software can  use to ensure that the  x87 exception pointers
(ip, dp,  opcode) are initialized to benign  values on every
context  switch.  Below  are just  a few  examples  of those
methods.

Critical to  the first two methods is  an OS-dependent "safe
address":  this  is  some  location which  can  be  accessed
without  faulting   and  whose   value  is  likely   in  the
processor's L1 data cache. This location will be loaded into
the x87 stack to ensure  that the x87 exception pointers are
set to a benign value.

[Note  that the  Data  Segment Descriptor  (DS)  that is  in
effect  when  the  kernel  executes the  clear  sequence  is
recorded in the x87  exception pointers. Depending on the OS
kernel  and its  mode,  this  DS may  be  from the  previous
process.  To prevent this,  the kernel should ensure that DS
is loaded with a  benign value before executing FXSAVE.  For
example, recent  32-bit Linux  kernels already reload  DS on
kernel entry.]
 


  + "FXRSTOR-centric" method

    This method sets the  x87 exception pointers to a benign
    state  just before  executing an  FXRSTOR.  It  makes no
    assumption about the state  of the current x87 exception
    pointers before executing  the restore sequence.  In the
    normal case, where ES is not set before the FXRSTOR, the
    "Clear  Sequence"  takes  approximately  14  cycles  (as
    measured on  an AMD Opteron). 
 
 

  ## Restore Code ...

  ## Begin_Clear_Sequence
	fnstsw	%ax		# Grab x87 ES bit
	ffree	st(7)		# Clear tag bit to remove
				#  -possible stack overflow
	bt	$7,%ax		# Test ES bit
	jnc	1f		# Jump if ES=0
	fnclex			# ES=1, so clear it so fild
				#  -can't trap
1:	fildl	safe_address	# Dummy Load from OS-dependent
				#  -"safe address" changes all
				#  -x87 exception pointers.
  ## End_Clear_Sequence
	fxrstor ...		# Now swap in process state


      
  + "FXSAVE-centric" method

    This  method  may not  apply  to  all operating  systems
    because  it requires  certain guarantees  between FXSAVE
    and a  subsequent FXRSTOR;  however, this is  the method
    that Linux  will likely choose.  This  approach sets the
    x87  exception pointers  to  a benign  state just  after
    executing an FXSAVE.  Between  that point and entry into
    another x87-using  process, the requirement  is that the
    x87 state  remains benign.  If anything  changes the x87
    exception  pointers in the  interim, then  software must
    clear  out or  save/restore the  state  explicitly again
    before executing an FXRSTOR.

    In  the normal  case,  where  ES is  not  set after  the
    FXSAVE,  the  "Clear  Sequence"  takes  approximately  7
    cycles (as  measured on  an AMD Opteron).   However, the
    added cycles  to the  FXSAVE code may  be much  less for
    operating systems, like  Linux, which currently place an
    unconditional  FNCLEX  after  the  FXSAVE.   The  "Clear
    Sequence"  replaces  the  unconditional  FNCLEX  with  a
    conditional one and may  actually *reduce* the number of
    cycles used for the FXSAVE code.


  ## FXSAVE Code
	fxsave save_image		# save old process state. 

  ## Begin_Clear_Sequence
	bt	$7,save_image.fsw	# Test saved ES bit
	jnc	1f			# Jump if ES=0
	fnclex				# ES=1, so clear it so fild
					#  -can't trap
1:	ffree	st(7)			# Clear tag bit to remove
					#  -possible stack overflow
	fildl	safe_address		# Dummy Load from OS-dependent
					#  -"safe address" changes all
					#  -x87 exception pointers.
  ## End_Clear_Sequence
	...
  ## Restore Code
	fxrstor ...			# Now swap in process state



  + FNSAVE and FRSTOR

    32-bit Operating  Systems can  use FNSAVE and  FRSTOR to
    always  save  and  restore  the complete  x87  execution
    state.   However,  because  these  instructions  do  not
    save/restore XMM registers or associated state, software
    must  explicitly perform  this operation.   In addition,
    because FSAVE/FNSAVE  do not  save the full  64-bit data
    and   instruction  pointers   for   x87  state,   64-bit
    applications  should  use  FXSAVE/FXRSTOR,  rather  than
    FSAVE/FRSTOR.



Processors Affected 
=================== 
It  is  AMD's  intent  that all  future  "AuthenticAMD"  AMD
processors  (those  that  return  "AuthenticAMD"  for  CPUID
vendor  string)  will  follow  the behavior  of  FXSAVE  and
FXRSTOR   as   documented   in   the   "AMD64   Architecture
Programmer's   Manual  Volume  5:   64-Bit  Media   and  x87
Floating-Point Instructions  Rev 3.06".  In  addition, these
CPUID Families of  "AuthenticAMD" AMD processors also follow
this behavior:

 + Family=06h:	All 7th generation AMD  processors (such as
		AMD Athlon, AMD Duron, AMD Athlon MP, 
		AMD Athlon XP, and AMD Sempron).
      
 + Family=0Fh:	All 8th generation AMD  processors (such as
		AMD Athlon64, AMD Athlon64 FX, AMD Opteron, 
		AMD Turion, and AMD Sempron).

AMD processors which return "Geode by NSCe" for CPUID vendor
string do not follow this behavior.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-04-19 22:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-19  7:05 Linux 2.6.16.9 Greg KH
2006-04-19  7:06 ` Greg KH
2006-04-19  7:54   ` Denis Vlasenko
2006-04-19 22:59 Brunner, Richard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®