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/kernel/process_32.c | |
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/kernel/process_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 9a62383e7c3c..b50604bb1e41 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <stdarg.h> | 12 | #include <stdarg.h> |
13 | 13 | ||
14 | #include <linux/stackprotector.h> | ||
14 | #include <linux/cpu.h> | 15 | #include <linux/cpu.h> |
15 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
@@ -91,6 +92,15 @@ void cpu_idle(void) | |||
91 | { | 92 | { |
92 | int cpu = smp_processor_id(); | 93 | int cpu = smp_processor_id(); |
93 | 94 | ||
95 | /* | ||
96 | * If we're the non-boot CPU, nothing set the stack canary up | ||
97 | * for us. CPU0 already has it initialized but no harm in | ||
98 | * doing it again. This is a good place for updating it, as | ||
99 | * we wont ever return from this function (so the invalid | ||
100 | * canaries already on the stack wont ever trigger). | ||
101 | */ | ||
102 | boot_init_stack_canary(); | ||
103 | |||
94 | current_thread_info()->status |= TS_POLLING; | 104 | current_thread_info()->status |= TS_POLLING; |
95 | 105 | ||
96 | /* endless idle loop with no priority at all */ | 106 | /* endless idle loop with no priority at all */ |