]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6-x86_64-stack-protector.patch
- sip conntrack
[packages/kernel.git] / linux-2.6-x86_64-stack-protector.patch
1 diff -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
35 diff -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
53 diff -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
71 diff -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 */
98 diff -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 
113 diff -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);
135 diff -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
154 diff -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.046332 seconds and 3 git commands to generate.