diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-19 06:36:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-19 06:36:09 -0500 |
commit | 7890ba8c87604ca4c2c73f7de846bf5305d743e4 (patch) | |
tree | f3f920c09b8de694b1bc1d4b878cfd2b0b98c913 | |
parent | 99937d6455cea95405ac681c86a857d0fcd530bd (diff) | |
parent | b2b062b8163391c42b3219d466ca1ac9742b9c7b (diff) |
Merge branch 'stackprotector' into core/percpu
-rw-r--r-- | arch/x86/Kconfig | 23 | ||||
-rw-r--r-- | arch/x86/Kconfig.debug | 1 | ||||
-rw-r--r-- | arch/x86/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/pda.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/stackprotector.h | 39 | ||||
-rw-r--r-- | arch/x86/include/asm/system.h | 6 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 13 | ||||
-rw-r--r-- | arch/x86/mm/fault.c | 7 | ||||
-rw-r--r-- | include/linux/magic.h | 1 | ||||
-rw-r--r-- | include/linux/sched.h | 16 | ||||
-rw-r--r-- | include/linux/stackprotector.h | 16 | ||||
-rw-r--r-- | init/main.c | 7 | ||||
-rw-r--r-- | kernel/exit.c | 5 | ||||
-rw-r--r-- | kernel/fork.c | 5 | ||||
-rw-r--r-- | kernel/panic.c | 12 | ||||
-rw-r--r-- | kernel/sched.c | 7 |
17 files changed, 134 insertions, 31 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 73f7fe8fd4d1..ef27aed6ff74 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1340,13 +1340,17 @@ config SECCOMP | |||
1340 | 1340 | ||
1341 | If unsure, say Y. Only embedded should say N here. | 1341 | If unsure, say Y. Only embedded should say N here. |
1342 | 1342 | ||
1343 | config CC_STACKPROTECTOR_ALL | ||
1344 | bool | ||
1345 | |||
1343 | config CC_STACKPROTECTOR | 1346 | config CC_STACKPROTECTOR |
1344 | bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" | 1347 | bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" |
1345 | depends on X86_64 && EXPERIMENTAL && BROKEN | 1348 | depends on X86_64 |
1349 | select CC_STACKPROTECTOR_ALL | ||
1346 | help | 1350 | help |
1347 | This option turns on the -fstack-protector GCC feature. This | 1351 | This option turns on the -fstack-protector GCC feature. This |
1348 | feature puts, at the beginning of critical functions, a canary | 1352 | feature puts, at the beginning of functions, a canary value on |
1349 | value on the stack just before the return address, and validates | 1353 | the stack just before the return address, and validates |
1350 | the value just before actually returning. Stack based buffer | 1354 | the value just before actually returning. Stack based buffer |
1351 | overflows (that need to overwrite this return address) now also | 1355 | overflows (that need to overwrite this return address) now also |
1352 | overwrite the canary, which gets detected and the attack is then | 1356 | overwrite the canary, which gets detected and the attack is then |
@@ -1354,15 +1358,8 @@ config CC_STACKPROTECTOR | |||
1354 | 1358 | ||
1355 | This feature requires gcc version 4.2 or above, or a distribution | 1359 | This feature requires gcc version 4.2 or above, or a distribution |
1356 | gcc with the feature backported. Older versions are automatically | 1360 | gcc with the feature backported. Older versions are automatically |
1357 | detected and for those versions, this configuration option is ignored. | 1361 | detected and for those versions, this configuration option is |
1358 | 1362 | ignored. (and a warning is printed during bootup) | |
1359 | config CC_STACKPROTECTOR_ALL | ||
1360 | bool "Use stack-protector for all functions" | ||
1361 | depends on CC_STACKPROTECTOR | ||
1362 | help | ||
1363 | Normally, GCC only inserts the canary value protection for | ||
1364 | functions that use large-ish on-stack buffers. By enabling | ||
1365 | this option, GCC will be asked to do this for ALL functions. | ||
1366 | 1363 | ||
1367 | source kernel/Kconfig.hz | 1364 | source kernel/Kconfig.hz |
1368 | 1365 | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 10d6cc3fd052..28f111461ca8 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -117,6 +117,7 @@ config DEBUG_RODATA | |||
117 | config DEBUG_RODATA_TEST | 117 | config DEBUG_RODATA_TEST |
118 | bool "Testcase for the DEBUG_RODATA feature" | 118 | bool "Testcase for the DEBUG_RODATA feature" |
119 | depends on DEBUG_RODATA | 119 | depends on DEBUG_RODATA |
120 | default y | ||
120 | help | 121 | help |
121 | This option enables a testcase for the DEBUG_RODATA | 122 | This option enables a testcase for the DEBUG_RODATA |
122 | feature as well as for the change_page_attr() infrastructure. | 123 | feature as well as for the change_page_attr() infrastructure. |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index d1a47adb5aec..cacee981d166 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -73,7 +73,7 @@ else | |||
73 | 73 | ||
74 | stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh | 74 | stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh |
75 | stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \ | 75 | stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \ |
76 | "$(CC)" -fstack-protector ) | 76 | "$(CC)" "-fstack-protector -DGCC_HAS_SP" ) |
77 | stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \ | 77 | stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \ |
78 | "$(CC)" -fstack-protector-all ) | 78 | "$(CC)" -fstack-protector-all ) |
79 | 79 | ||
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index c31ca048a901..5976cd803e9a 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h | |||
@@ -17,11 +17,9 @@ struct x8664_pda { | |||
17 | unsigned long unused4; | 17 | unsigned long unused4; |
18 | int unused5; | 18 | int unused5; |
19 | unsigned int unused6; /* 36 was cpunumber */ | 19 | unsigned int unused6; /* 36 was cpunumber */ |
20 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
21 | unsigned long stack_canary; /* 40 stack canary value */ | 20 | unsigned long stack_canary; /* 40 stack canary value */ |
22 | /* gcc-ABI: this canary MUST be at | 21 | /* gcc-ABI: this canary MUST be at |
23 | offset 40!!! */ | 22 | offset 40!!! */ |
24 | #endif | ||
25 | short in_bootmem; /* pda lives in bootmem */ | 23 | short in_bootmem; /* pda lives in bootmem */ |
26 | } ____cacheline_aligned_in_smp; | 24 | } ____cacheline_aligned_in_smp; |
27 | 25 | ||
@@ -42,4 +40,6 @@ extern void pda_init(int); | |||
42 | 40 | ||
43 | #endif | 41 | #endif |
44 | 42 | ||
43 | #define refresh_stack_canary() write_pda(stack_canary, current->stack_canary) | ||
44 | |||
45 | #endif /* _ASM_X86_PDA_H */ | 45 | #endif /* _ASM_X86_PDA_H */ |
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h new file mode 100644 index 000000000000..c7f0d10bae7b --- /dev/null +++ b/arch/x86/include/asm/stackprotector.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef _ASM_STACKPROTECTOR_H | ||
2 | #define _ASM_STACKPROTECTOR_H 1 | ||
3 | |||
4 | #include <asm/tsc.h> | ||
5 | #include <asm/pda.h> | ||
6 | |||
7 | /* | ||
8 | * Initialize the stackprotector canary value. | ||
9 | * | ||
10 | * NOTE: this must only be called from functions that never return, | ||
11 | * and it must always be inlined. | ||
12 | */ | ||
13 | static __always_inline void boot_init_stack_canary(void) | ||
14 | { | ||
15 | u64 canary; | ||
16 | u64 tsc; | ||
17 | |||
18 | /* | ||
19 | * If we're the non-boot CPU, nothing set the PDA stack | ||
20 | * canary up for us - and if we are the boot CPU we have | ||
21 | * a 0 stack canary. This is a good place for updating | ||
22 | * it, as we wont ever return from this function (so the | ||
23 | * invalid canaries already on the stack wont ever | ||
24 | * trigger). | ||
25 | * | ||
26 | * We both use the random pool and the current TSC as a source | ||
27 | * of randomness. The TSC only matters for very early init, | ||
28 | * there it already has some randomness on most systems. Later | ||
29 | * on during the bootup the random pool has true entropy too. | ||
30 | */ | ||
31 | get_random_bytes(&canary, sizeof(canary)); | ||
32 | tsc = __native_read_tsc(); | ||
33 | canary += tsc + (tsc << 32UL); | ||
34 | |||
35 | current->stack_canary = canary; | ||
36 | write_pda(stack_canary, canary); | ||
37 | } | ||
38 | |||
39 | #endif | ||
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index d1dc27dba36d..8cadfe9b1194 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
@@ -95,6 +95,8 @@ do { \ | |||
95 | ".globl thread_return\n" \ | 95 | ".globl thread_return\n" \ |
96 | "thread_return:\n\t" \ | 96 | "thread_return:\n\t" \ |
97 | "movq "__percpu_arg([current_task])",%%rsi\n\t" \ | 97 | "movq "__percpu_arg([current_task])",%%rsi\n\t" \ |
98 | "movq %P[task_canary](%%rsi),%%r8\n\t" \ | ||
99 | "movq %%r8,%%gs:%P[pda_canary]\n\t" \ | ||
98 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ | 100 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ |
99 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ | 101 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ |
100 | "movq %%rax,%%rdi\n\t" \ | 102 | "movq %%rax,%%rdi\n\t" \ |
@@ -106,7 +108,9 @@ do { \ | |||
106 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ | 108 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ |
107 | [tif_fork] "i" (TIF_FORK), \ | 109 | [tif_fork] "i" (TIF_FORK), \ |
108 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ | 110 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ |
109 | [current_task] "m" (per_cpu_var(current_task)) \ | 111 | [task_canary] "i" (offsetof(struct task_struct, stack_canary)),\ |
112 | [current_task] "m" (per_cpu_var(current_task)), \ | ||
113 | [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\ | ||
110 | : "memory", "cc" __EXTRA_CLOBBER) | 114 | : "memory", "cc" __EXTRA_CLOBBER) |
111 | #endif | 115 | #endif |
112 | 116 | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index d364df03c1d6..eb074530c7d3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -23,6 +23,7 @@ nostackp := $(call cc-option, -fno-stack-protector) | |||
23 | CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) | 23 | CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) |
24 | CFLAGS_hpet.o := $(nostackp) | 24 | CFLAGS_hpet.o := $(nostackp) |
25 | CFLAGS_tsc.o := $(nostackp) | 25 | CFLAGS_tsc.o := $(nostackp) |
26 | CFLAGS_paravirt.o := $(nostackp) | ||
26 | 27 | ||
27 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o | 28 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o |
28 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o | 29 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4523ff88a69d..aa89eabf09e0 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <stdarg.h> | 17 | #include <stdarg.h> |
18 | 18 | ||
19 | #include <linux/stackprotector.h> | ||
19 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
21 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
@@ -117,6 +118,17 @@ static inline void play_dead(void) | |||
117 | void cpu_idle(void) | 118 | void cpu_idle(void) |
118 | { | 119 | { |
119 | current_thread_info()->status |= TS_POLLING; | 120 | current_thread_info()->status |= TS_POLLING; |
121 | |||
122 | /* | ||
123 | * If we're the non-boot CPU, nothing set the PDA stack | ||
124 | * canary up for us - and if we are the boot CPU we have | ||
125 | * a 0 stack canary. This is a good place for updating | ||
126 | * it, as we wont ever return from this function (so the | ||
127 | * invalid canaries already on the stack wont ever | ||
128 | * trigger): | ||
129 | */ | ||
130 | boot_init_stack_canary(); | ||
131 | |||
120 | /* endless idle loop with no priority at all */ | 132 | /* endless idle loop with no priority at all */ |
121 | while (1) { | 133 | while (1) { |
122 | tick_nohz_stop_sched_tick(1); | 134 | tick_nohz_stop_sched_tick(1); |
@@ -627,7 +639,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
627 | (unsigned long)task_stack_page(next_p) + | 639 | (unsigned long)task_stack_page(next_p) + |
628 | THREAD_SIZE - KERNEL_STACK_OFFSET); | 640 | THREAD_SIZE - KERNEL_STACK_OFFSET); |
629 | #ifdef CONFIG_CC_STACKPROTECTOR | 641 | #ifdef CONFIG_CC_STACKPROTECTOR |
630 | write_pda(stack_canary, next_p->stack_canary); | ||
631 | /* | 642 | /* |
632 | * Build time only check to make sure the stack_canary is at | 643 | * Build time only check to make sure the stack_canary is at |
633 | * offset 40 in the pda; this is a gcc ABI requirement | 644 | * offset 40 in the pda; this is a gcc ABI requirement |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 90dfae511a41..37242c405f16 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kprobes.h> | 26 | #include <linux/kprobes.h> |
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/kdebug.h> | 28 | #include <linux/kdebug.h> |
29 | #include <linux/magic.h> | ||
29 | 30 | ||
30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
31 | #include <asm/desc.h> | 32 | #include <asm/desc.h> |
@@ -589,6 +590,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
589 | unsigned long address; | 590 | unsigned long address; |
590 | int write, si_code; | 591 | int write, si_code; |
591 | int fault; | 592 | int fault; |
593 | unsigned long *stackend; | ||
594 | |||
592 | #ifdef CONFIG_X86_64 | 595 | #ifdef CONFIG_X86_64 |
593 | unsigned long flags; | 596 | unsigned long flags; |
594 | int sig; | 597 | int sig; |
@@ -841,6 +844,10 @@ no_context: | |||
841 | 844 | ||
842 | show_fault_oops(regs, error_code, address); | 845 | show_fault_oops(regs, error_code, address); |
843 | 846 | ||
847 | stackend = end_of_stack(tsk); | ||
848 | if (*stackend != STACK_END_MAGIC) | ||
849 | printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); | ||
850 | |||
844 | tsk->thread.cr2 = address; | 851 | tsk->thread.cr2 = address; |
845 | tsk->thread.trap_no = 14; | 852 | tsk->thread.trap_no = 14; |
846 | tsk->thread.error_code = error_code; | 853 | tsk->thread.error_code = error_code; |
diff --git a/include/linux/magic.h b/include/linux/magic.h index 439f6f3cb0c4..561a5ff92c88 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h | |||
@@ -47,4 +47,5 @@ | |||
47 | #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA | 47 | #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA |
48 | #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA | 48 | #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA |
49 | 49 | ||
50 | #define STACK_END_MAGIC 0x57AC6E9D | ||
50 | #endif /* __LINUX_MAGIC_H__ */ | 51 | #endif /* __LINUX_MAGIC_H__ */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 4cae9b81a1f8..a85b0cec7d12 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1157,10 +1157,9 @@ struct task_struct { | |||
1157 | pid_t pid; | 1157 | pid_t pid; |
1158 | pid_t tgid; | 1158 | pid_t tgid; |
1159 | 1159 | ||
1160 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
1161 | /* Canary value for the -fstack-protector gcc feature */ | 1160 | /* Canary value for the -fstack-protector gcc feature */ |
1162 | unsigned long stack_canary; | 1161 | unsigned long stack_canary; |
1163 | #endif | 1162 | |
1164 | /* | 1163 | /* |
1165 | * pointers to (original) parent process, youngest child, younger sibling, | 1164 | * pointers to (original) parent process, youngest child, younger sibling, |
1166 | * older sibling, respectively. (p->father can be replaced with | 1165 | * older sibling, respectively. (p->father can be replaced with |
@@ -2066,6 +2065,19 @@ static inline int object_is_on_stack(void *obj) | |||
2066 | 2065 | ||
2067 | extern void thread_info_cache_init(void); | 2066 | extern void thread_info_cache_init(void); |
2068 | 2067 | ||
2068 | #ifdef CONFIG_DEBUG_STACK_USAGE | ||
2069 | static inline unsigned long stack_not_used(struct task_struct *p) | ||
2070 | { | ||
2071 | unsigned long *n = end_of_stack(p); | ||
2072 | |||
2073 | do { /* Skip over canary */ | ||
2074 | n++; | ||
2075 | } while (!*n); | ||
2076 | |||
2077 | return (unsigned long)n - (unsigned long)end_of_stack(p); | ||
2078 | } | ||
2079 | #endif | ||
2080 | |||
2069 | /* set thread flags in other task's structures | 2081 | /* set thread flags in other task's structures |
2070 | * - see asm/thread_info.h for TIF_xxxx flags available | 2082 | * - see asm/thread_info.h for TIF_xxxx flags available |
2071 | */ | 2083 | */ |
diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h new file mode 100644 index 000000000000..6f3e54c704c0 --- /dev/null +++ b/include/linux/stackprotector.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _LINUX_STACKPROTECTOR_H | ||
2 | #define _LINUX_STACKPROTECTOR_H 1 | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <linux/sched.h> | ||
6 | #include <linux/random.h> | ||
7 | |||
8 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
9 | # include <asm/stackprotector.h> | ||
10 | #else | ||
11 | static inline void boot_init_stack_canary(void) | ||
12 | { | ||
13 | } | ||
14 | #endif | ||
15 | |||
16 | #endif | ||
diff --git a/init/main.c b/init/main.c index 844209453c02..bfe4fb0c9842 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/proc_fs.h> | 14 | #include <linux/proc_fs.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/syscalls.h> | 16 | #include <linux/syscalls.h> |
17 | #include <linux/stackprotector.h> | ||
17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
18 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
@@ -539,6 +540,12 @@ asmlinkage void __init start_kernel(void) | |||
539 | */ | 540 | */ |
540 | lockdep_init(); | 541 | lockdep_init(); |
541 | debug_objects_early_init(); | 542 | debug_objects_early_init(); |
543 | |||
544 | /* | ||
545 | * Set up the the initial canary ASAP: | ||
546 | */ | ||
547 | boot_init_stack_canary(); | ||
548 | |||
542 | cgroup_init_early(); | 549 | cgroup_init_early(); |
543 | 550 | ||
544 | local_irq_disable(); | 551 | local_irq_disable(); |
diff --git a/kernel/exit.c b/kernel/exit.c index c7740fa3252c..2a803c28df9e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -977,12 +977,9 @@ static void check_stack_usage(void) | |||
977 | { | 977 | { |
978 | static DEFINE_SPINLOCK(low_water_lock); | 978 | static DEFINE_SPINLOCK(low_water_lock); |
979 | static int lowest_to_date = THREAD_SIZE; | 979 | static int lowest_to_date = THREAD_SIZE; |
980 | unsigned long *n = end_of_stack(current); | ||
981 | unsigned long free; | 980 | unsigned long free; |
982 | 981 | ||
983 | while (*n == 0) | 982 | free = stack_not_used(current); |
984 | n++; | ||
985 | free = (unsigned long)n - (unsigned long)end_of_stack(current); | ||
986 | 983 | ||
987 | if (free >= lowest_to_date) | 984 | if (free >= lowest_to_date) |
988 | return; | 985 | return; |
diff --git a/kernel/fork.c b/kernel/fork.c index 1d68f1255dd8..4a9b318dad0d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/proc_fs.h> | 61 | #include <linux/proc_fs.h> |
62 | #include <linux/blkdev.h> | 62 | #include <linux/blkdev.h> |
63 | #include <trace/sched.h> | 63 | #include <trace/sched.h> |
64 | #include <linux/magic.h> | ||
64 | 65 | ||
65 | #include <asm/pgtable.h> | 66 | #include <asm/pgtable.h> |
66 | #include <asm/pgalloc.h> | 67 | #include <asm/pgalloc.h> |
@@ -212,6 +213,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
212 | { | 213 | { |
213 | struct task_struct *tsk; | 214 | struct task_struct *tsk; |
214 | struct thread_info *ti; | 215 | struct thread_info *ti; |
216 | unsigned long *stackend; | ||
217 | |||
215 | int err; | 218 | int err; |
216 | 219 | ||
217 | prepare_to_copy(orig); | 220 | prepare_to_copy(orig); |
@@ -237,6 +240,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
237 | goto out; | 240 | goto out; |
238 | 241 | ||
239 | setup_thread_stack(tsk, orig); | 242 | setup_thread_stack(tsk, orig); |
243 | stackend = end_of_stack(tsk); | ||
244 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | ||
240 | 245 | ||
241 | #ifdef CONFIG_CC_STACKPROTECTOR | 246 | #ifdef CONFIG_CC_STACKPROTECTOR |
242 | tsk->stack_canary = get_random_int(); | 247 | tsk->stack_canary = get_random_int(); |
diff --git a/kernel/panic.c b/kernel/panic.c index 2a2ff36ff44d..33cab3de1763 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -74,6 +74,9 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
74 | vsnprintf(buf, sizeof(buf), fmt, args); | 74 | vsnprintf(buf, sizeof(buf), fmt, args); |
75 | va_end(args); | 75 | va_end(args); |
76 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); | 76 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); |
77 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
78 | dump_stack(); | ||
79 | #endif | ||
77 | bust_spinlocks(0); | 80 | bust_spinlocks(0); |
78 | 81 | ||
79 | /* | 82 | /* |
@@ -355,15 +358,22 @@ EXPORT_SYMBOL(warn_slowpath); | |||
355 | #endif | 358 | #endif |
356 | 359 | ||
357 | #ifdef CONFIG_CC_STACKPROTECTOR | 360 | #ifdef CONFIG_CC_STACKPROTECTOR |
361 | |||
362 | #ifndef GCC_HAS_SP | ||
363 | #warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. | ||
364 | #endif | ||
365 | |||
358 | /* | 366 | /* |
359 | * Called when gcc's -fstack-protector feature is used, and | 367 | * Called when gcc's -fstack-protector feature is used, and |
360 | * gcc detects corruption of the on-stack canary value | 368 | * gcc detects corruption of the on-stack canary value |
361 | */ | 369 | */ |
362 | void __stack_chk_fail(void) | 370 | void __stack_chk_fail(void) |
363 | { | 371 | { |
364 | panic("stack-protector: Kernel stack is corrupted"); | 372 | panic("stack-protector: Kernel stack is corrupted in: %p\n", |
373 | __builtin_return_address(0)); | ||
365 | } | 374 | } |
366 | EXPORT_SYMBOL(__stack_chk_fail); | 375 | EXPORT_SYMBOL(__stack_chk_fail); |
376 | |||
367 | #endif | 377 | #endif |
368 | 378 | ||
369 | core_param(panic, panic_timeout, int, 0644); | 379 | core_param(panic, panic_timeout, int, 0644); |
diff --git a/kernel/sched.c b/kernel/sched.c index 8be2c13b50d0..1d2909067040 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -5939,12 +5939,7 @@ void sched_show_task(struct task_struct *p) | |||
5939 | printk(KERN_CONT " %016lx ", thread_saved_pc(p)); | 5939 | printk(KERN_CONT " %016lx ", thread_saved_pc(p)); |
5940 | #endif | 5940 | #endif |
5941 | #ifdef CONFIG_DEBUG_STACK_USAGE | 5941 | #ifdef CONFIG_DEBUG_STACK_USAGE |
5942 | { | 5942 | free = stack_not_used(p); |
5943 | unsigned long *n = end_of_stack(p); | ||
5944 | while (!*n) | ||
5945 | n++; | ||
5946 | free = (unsigned long)n - (unsigned long)end_of_stack(p); | ||
5947 | } | ||
5948 | #endif | 5943 | #endif |
5949 | printk(KERN_CONT "%5lu %5d %6d\n", free, | 5944 | printk(KERN_CONT "%5lu %5d %6d\n", free, |
5950 | task_pid_nr(p), task_pid_nr(p->real_parent)); | 5945 | task_pid_nr(p), task_pid_nr(p->real_parent)); |