diff options
author | Tejun Heo <tj@kernel.org> | 2009-02-11 02:31:00 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-11 05:33:49 -0500 |
commit | 5c79d2a517a9905599d192db8ce77ab5f1a2faca (patch) | |
tree | 11f550a59b9b653fbd6c54b37effbf2d4a750fb5 /arch/x86/include/asm/system.h | |
parent | 60a5317ff0f42dd313094b88f809f63041568b08 (diff) |
x86: fix x86_32 stack protector bugs
Impact: fix x86_32 stack protector
Brian Gerst found out that %gs was being initialized to stack_canary
instead of stack_canary - 20, which basically gave the same canary
value for all threads. Fixing this also exposed the following bugs.
* cpu_idle() didn't call boot_init_stack_canary()
* stack canary switching in switch_to() was being done too late making
the initial run of a new thread use the old stack canary value.
Fix all of them and while at it update comment in cpu_idle() about
calling boot_init_stack_canary().
Reported-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm/system.h')
-rw-r--r-- | arch/x86/include/asm/system.h | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 2692ee8ef031..7a80f72bec47 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
@@ -25,13 +25,11 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
25 | 25 | ||
26 | #ifdef CONFIG_CC_STACKPROTECTOR | 26 | #ifdef CONFIG_CC_STACKPROTECTOR |
27 | #define __switch_canary \ | 27 | #define __switch_canary \ |
28 | "movl "__percpu_arg([current_task])",%%ebx\n\t" \ | 28 | "movl %P[task_canary](%[next]), %%ebx\n\t" \ |
29 | "movl %P[task_canary](%%ebx),%%ebx\n\t" \ | 29 | "movl %%ebx, "__percpu_arg([stack_canary])"\n\t" |
30 | "movl %%ebx,"__percpu_arg([stack_canary])"\n\t" | ||
31 | #define __switch_canary_oparam \ | 30 | #define __switch_canary_oparam \ |
32 | , [stack_canary] "=m" (per_cpu_var(stack_canary)) | 31 | , [stack_canary] "=m" (per_cpu_var(stack_canary)) |
33 | #define __switch_canary_iparam \ | 32 | #define __switch_canary_iparam \ |
34 | , [current_task] "m" (per_cpu_var(current_task)) \ | ||
35 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) | 33 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) |
36 | #else /* CC_STACKPROTECTOR */ | 34 | #else /* CC_STACKPROTECTOR */ |
37 | #define __switch_canary | 35 | #define __switch_canary |
@@ -60,9 +58,9 @@ do { \ | |||
60 | "movl %[next_sp],%%esp\n\t" /* restore ESP */ \ | 58 | "movl %[next_sp],%%esp\n\t" /* restore ESP */ \ |
61 | "movl $1f,%[prev_ip]\n\t" /* save EIP */ \ | 59 | "movl $1f,%[prev_ip]\n\t" /* save EIP */ \ |
62 | "pushl %[next_ip]\n\t" /* restore EIP */ \ | 60 | "pushl %[next_ip]\n\t" /* restore EIP */ \ |
61 | __switch_canary \ | ||
63 | "jmp __switch_to\n" /* regparm call */ \ | 62 | "jmp __switch_to\n" /* regparm call */ \ |
64 | "1:\t" \ | 63 | "1:\t" \ |
65 | __switch_canary \ | ||
66 | "popl %%ebp\n\t" /* restore EBP */ \ | 64 | "popl %%ebp\n\t" /* restore EBP */ \ |
67 | "popfl\n" /* restore flags */ \ | 65 | "popfl\n" /* restore flags */ \ |
68 | \ | 66 | \ |