aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/head_32.S
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-02-09 08:17:40 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-09 18:42:01 -0500
commit60a5317ff0f42dd313094b88f809f63041568b08 (patch)
tree307dfd9715fbc9ff83c3c3ae3b0e8f03888083f2 /arch/x86/kernel/head_32.S
parentccbeed3a05908d201b47b6c3dd1a373138bba566 (diff)
x86: implement x86_32 stack protector
Impact: stack protector for x86_32 Implement stack protector for x86_32. GDT entry 28 is used for it. It's set to point to stack_canary-20 and have the length of 24 bytes. CONFIG_CC_STACKPROTECTOR turns off CONFIG_X86_32_LAZY_GS and sets %gs to the stack canary segment on entry. As %gs is otherwise unused by the kernel, the canary can be anywhere. It's defined as a percpu variable. x86_32 exception handlers take register frame on stack directly as struct pt_regs. With -fstack-protector turned on, gcc copies the whole structure after the stack canary and (of course) doesn't copy back on return thus losing all changed. For now, -fno-stack-protector is added to all files which contain those functions. We definitely need something better. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/head_32.S')
-rw-r--r--arch/x86/kernel/head_32.S20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 24c0e5cd71e3..924e31615fb6 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -19,6 +19,7 @@
19#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
20#include <asm/setup.h> 20#include <asm/setup.h>
21#include <asm/processor-flags.h> 21#include <asm/processor-flags.h>
22#include <asm/percpu.h>
22 23
23/* Physical address */ 24/* Physical address */
24#define pa(X) ((X) - __PAGE_OFFSET) 25#define pa(X) ((X) - __PAGE_OFFSET)
@@ -437,8 +438,25 @@ is386: movl $2,%ecx # set MP
437 movl $(__KERNEL_PERCPU), %eax 438 movl $(__KERNEL_PERCPU), %eax
438 movl %eax,%fs # set this cpu's percpu 439 movl %eax,%fs # set this cpu's percpu
439 440
440 xorl %eax,%eax # Clear GS and LDT 441#ifdef CONFIG_CC_STACKPROTECTOR
442 /*
443 * The linker can't handle this by relocation. Manually set
444 * base address in stack canary segment descriptor.
445 */
446 cmpb $0,ready
447 jne 1f
448 movl $per_cpu__gdt_page,%eax
449 movl $per_cpu__stack_canary,%ecx
450 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
451 shrl $16, %ecx
452 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
453 movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
4541:
455#endif
456 movl $(__KERNEL_STACK_CANARY),%eax
441 movl %eax,%gs 457 movl %eax,%gs
458
459 xorl %eax,%eax # Clear LDT
442 lldt %ax 460 lldt %ax
443 461
444 cld # gcc2 wants the direction flag cleared at all times 462 cld # gcc2 wants the direction flag cleared at all times