]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.6-x86_64-stack-protector.patch
- addedd Linux-ABI support. Bcond, default disabled.
[packages/kernel.git] / linux-2.6-x86_64-stack-protector.patch
CommitLineData
c5a9e72a
PS
1diff -uNr linux-2.6.16.orig/arch/x86_64/Kconfig linux-2.6.16/arch/x86_64/Kconfig
2--- linux-2.6.16.orig/arch/x86_64/Kconfig 2006-08-27 09:02:03.754054500 +0200
3+++ linux-2.6.16/arch/x86_64/Kconfig 2006-08-27 09:12:33.514413750 +0200
4@@ -464,6 +464,30 @@
5
6 If unsure, say Y. Only embedded should say N here.
7
8+config CC_STACKPROTECTOR
9+ bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)"
10+ depends on EXPERIMENTAL
11+ help
12+ This option turns on the -fstack-protector GCC feature. This
13+ feature puts, at the beginning of critical functions, a canary
14+ value on the stack just before the return address, and validates
15+ the value just before actually returning. Stack based buffer
16+ overflows (that need to overwrite this return address) now also
17+ overwrite the canary, which gets detected and the attack is then
18+ neutralized via a kernel panic.
19+
20+ This feature requires gcc version 4.2 or above, or a distribution
21+ gcc with the feature backported. Older versions are automatically
22+ detected and for those versions, this configuration option is ignored.
23+
24+config CC_STACKPROTECTOR_ALL
25+ bool "Use stack-protector for all functions"
26+ depends on CC_STACKPROTECTOR
27+ help
28+ Normally, GCC only inserts the canary value protection for
29+ functions that use large-ish on-stack buffers. By enabling
30+ this option, GCC will be asked to do this for ALL functions.
31+
32 source kernel/Kconfig.hz
33
34 endmenu
35diff -uNr linux-2.6.16.orig/arch/x86_64/kernel/process.c linux-2.6.16/arch/x86_64/kernel/process.c
36--- linux-2.6.16.orig/arch/x86_64/kernel/process.c 2006-08-27 09:02:03.798035250 +0200
37+++ linux-2.6.16/arch/x86_64/kernel/process.c 2006-08-27 09:12:52.254211500 +0200
38@@ -598,6 +598,14 @@
39
40 write_pda(kernelstack,
41 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
42+#ifdef CONFIG_CC_STACKPROTECTOR
43+ write_pda(stack_canary, next_p->stack_canary);
44+ /*
45+ * Build time only check to make sure the stack_canary is at
46+ * offset 40 in the pda; this is a gcc ABI requirement
47+ */
48+ BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
49+#endif
50
51 /*
52 * Now maybe reload the debug registers
53diff -uNr linux-2.6.16.orig/arch/x86_64/Makefile linux-2.6.16/arch/x86_64/Makefile
54--- linux-2.6.16.orig/arch/x86_64/Makefile 2006-03-20 06:53:29.000000000 +0100
55+++ linux-2.6.16/arch/x86_64/Makefile 2006-08-27 09:13:17.898987000 +0200
56@@ -29,6 +29,14 @@
57
58 cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
59 cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
60+
61+stack-protector = $(shell $(CONFIG_SHELL) \
62+ $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(1))
63+cflags-$(CONFIG_CC_STACKPROTECTOR) += \
64+ $(call stack-protector, $(CC) -fstack-protector)
65+cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += \
66+ $(call stack-protector, $(CC) -fstack-protector-all)
67+
68 CFLAGS += $(cflags-y)
69
70 CFLAGS += -m64
71diff -uNr linux-2.6.16.orig/include/asm-x86_64/pda.h linux-2.6.16/include/asm-x86_64/pda.h
72--- linux-2.6.16.orig/include/asm-x86_64/pda.h 2006-03-20 06:53:29.000000000 +0100
73+++ linux-2.6.16/include/asm-x86_64/pda.h 2006-08-27 09:12:52.254211500 +0200
74@@ -9,14 +9,16 @@
75
76 /* Per processor datastructure. %gs points to it while the kernel runs */
77 struct x8664_pda {
78- struct task_struct *pcurrent; /* Current process */
79- unsigned long data_offset; /* Per cpu data offset from linker address */
80- unsigned long kernelstack; /* top of kernel stack for current */
81- unsigned long oldrsp; /* user rsp for system call */
82-#if DEBUG_STKSZ > EXCEPTION_STKSZ
83- unsigned long debugstack; /* #DB/#BP stack. */
84+ struct task_struct *pcurrent; /* 0 */ /* Current process */
85+ unsigned long data_offset; /* 8 */ /* Per cpu data offset from linker address */
86+ unsigned long kernelstack; /* 16 */ /* top of kernel stack for current */
87+ unsigned long oldrsp; /* 24 */ /* user rsp for system call */
88+ unsigned long debugstack; /* 32 */ /* #DB/#BP stack. */
89+#ifdef CONFIG_CC_STACKPROTECTOR
90+ unsigned long stack_canary; /* 40 */ /* stack canary value */
91+ /* gcc-ABI: this canary MUST be at offset 40!!! */
92 #endif
93- int irqcount; /* Irq nesting counter. Starts with -1 */
94+ int irqcount; /* 48 */ /* Irq nesting counter. Starts with -1 */
95 int cpunumber; /* Logical CPU number */
96 char *irqstackptr; /* top of irqstack */
97 int nodenumber; /* number of current node */
98diff -uNr linux-2.6.16.orig/include/linux/sched.h linux-2.6.16/include/linux/sched.h
99--- linux-2.6.16.orig/include/linux/sched.h 2006-08-27 09:02:04.285821750 +0200
100+++ linux-2.6.16/include/linux/sched.h 2006-08-27 09:12:52.254211500 +0200
101@@ -755,6 +755,11 @@
102 unsigned did_exec:1;
103 pid_t pid;
104 pid_t tgid;
105+
106+#ifdef CONFIG_CC_STACKPROTECTOR
107+ /* Canary value for the -fstack-protector gcc feature */
108+ unsigned long stack_canary;
109+#endif
110 /*
111 * pointers to (original) parent process, youngest child, younger sibling,
112 * older sibling, respectively. (p->father can be replaced with
113diff -uNr linux-2.6.16.orig/kernel/fork.c linux-2.6.16/kernel/fork.c
114--- linux-2.6.16.orig/kernel/fork.c 2006-08-27 09:02:04.097904000 +0200
115+++ linux-2.6.16/kernel/fork.c 2006-08-27 09:12:52.254211500 +0200
116@@ -45,6 +45,7 @@
117 #include <linux/acct.h>
118 #include <linux/cn_proc.h>
119 #include <linux/vs_context.h>
120+#include <linux/random.h>
121 #include <linux/vs_network.h>
122 #include <linux/vs_limit.h>
123 #include <linux/vs_memory.h>
124@@ -184,6 +185,10 @@
125 tsk->thread_info = ti;
126 setup_thread_stack(tsk, orig);
127
128+#ifdef CONFIG_CC_STACKPROTECTOR
129+ tsk->stack_canary = get_random_int();
130+#endif
131+
132 /* One for us, one for whoever does the "release_task()" (usually parent) */
133 atomic_set(&tsk->usage,2);
134 atomic_set(&tsk->fs_excl, 0);
135diff -uNr linux-2.6.16.orig/kernel/panic.c linux-2.6.16/kernel/panic.c
136--- linux-2.6.16.orig/kernel/panic.c 2006-03-20 06:53:29.000000000 +0100
137+++ linux-2.6.16/kernel/panic.c 2006-08-27 09:13:06.200107500 +0200
138@@ -174,3 +174,15 @@
139 tainted |= flag;
140 }
141 EXPORT_SYMBOL(add_taint);
142+
143+#ifdef CONFIG_CC_STACKPROTECTOR
144+/*
145+ * Called when gcc's -fstack-protector feature is used, and
146+ * gcc detects corruption of the on-stack canary value
147+ */
148+void __stack_chk_fail(void)
149+{
150+ panic("stack-protector: Kernel stack is corrupted");
151+}
152+EXPORT_SYMBOL(__stack_chk_fail);
153+#endif
154diff -uNr linux-2.6.16.orig/scripts/gcc-x86_64-has-stack-protector.sh linux-2.6.16/scripts/gcc-x86_64-has-stack-protector.sh
155--- linux-2.6.16.orig/scripts/gcc-x86_64-has-stack-protector.sh 1970-01-01 01:00:00.000000000 +0100
156+++ linux-2.6.16/scripts/gcc-x86_64-has-stack-protector.sh 2006-08-27 09:13:17.898987000 +0200
157@@ -0,0 +1,6 @@
158+#!/bin/sh
159+
160+echo "int foo(void) { char X[200]; return 3; }" | $1 -S -xc -c -O0 -mcmodel=kernel -fstack-protector - -o - | grep -q "%gs"
161+if [ "$?" -eq "0" ] ; then
162+ echo $2
163+fi
This page took 0.06283 seconds and 4 git commands to generate.