i386: save/restore eflags in context switch (CVE-2006-5173)

(And reset it on new thread creation)

It turns out that eflags is important to save and restore not just
because of iopl, but due to the magic bits like the NT bit, which we
don't want leaking between different threads.

Backported to 2.6.16 by Chuck Ebbert <76306.1226@compuserve.com>
[Backport consisted of removing the CFI annotations.]

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
This commit is contained in:
Linus Torvalds
2007-01-04 23:23:27 +01:00
committed by Adrian Bunk
parent bb3e712f45
commit 09d9056ce6
2 changed files with 9 additions and 1 deletions
+2
View File
@@ -128,6 +128,8 @@ ENTRY(ret_from_fork)
call schedule_tail
GET_THREAD_INFO(%ebp)
popl %eax
pushl $0x0202 # Reset kernel eflags
popfl
jmp syscall_exit
/*
+7 -1
View File
@@ -12,9 +12,14 @@
struct task_struct; /* one of the stranger aspects of C forward declarations.. */
extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
/*
* Saving eflags is important. It switches not only IOPL between tasks,
* it also protects other tasks from NT leaking through sysenter etc.
*/
#define switch_to(prev,next,last) do { \
unsigned long esi,edi; \
asm volatile("pushl %%ebp\n\t" \
asm volatile("pushfl\n\t" /* Save flags */ \
"pushl %%ebp\n\t" \
"movl %%esp,%0\n\t" /* save ESP */ \
"movl %5,%%esp\n\t" /* restore ESP */ \
"movl $1f,%1\n\t" /* save EIP */ \
@@ -22,6 +27,7 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc
"jmp __switch_to\n" \
"1:\t" \
"popl %%ebp\n\t" \
"popfl" \
:"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
"=a" (last),"=S" (esi),"=D" (edi) \
:"m" (next->thread.esp),"m" (next->thread.eip), \