* 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®