aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2010-05-24 23:55:42 -0400
committerNicolas Pitre <nico@fluxnic.net>2010-06-14 21:31:00 -0400
commitc743f38013aeff58ef6252601e397b5ba281c633 (patch)
treeb364e1690aff8a0dd97a83d4cb17bcadcdb5bd19 /arch/arm
parentcc92c28b2db5b406657ecc05235d4ca4e222ae34 (diff)
ARM: initial stack protector (-fstack-protector) support
This is the very basic stuff without the changing canary upon task switch yet. Just the Kconfig option and a constant canary value initialized at boot time. Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/include/asm/stackprotector.h38
-rw-r--r--arch/arm/kernel/process.c6
4 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1f254bd6c937..f160b93691cd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1374,6 +1374,18 @@ config UACCESS_WITH_MEMCPY
1374 However, if the CPU data cache is using a write-allocate mode, 1374 However, if the CPU data cache is using a write-allocate mode,
1375 this option is unlikely to provide any performance gain. 1375 this option is unlikely to provide any performance gain.
1376 1376
1377config CC_STACKPROTECTOR
1378 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
1379 help
1380 This option turns on the -fstack-protector GCC feature. This
1381 feature puts, at the beginning of functions, a canary value on
1382 the stack just before the return address, and validates
1383 the value just before actually returning. Stack based buffer
1384 overflows (that need to overwrite this return address) now also
1385 overwrite the canary, which gets detected and the attack is then
1386 neutralized via a kernel panic.
1387 This feature requires gcc version 4.2 or above.
1388
1377endmenu 1389endmenu
1378 1390
1379menu "Boot options" 1391menu "Boot options"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 64ba313724d2..ddf6da158ad8 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -34,6 +34,10 @@ ifeq ($(CONFIG_FRAME_POINTER),y)
34KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog 34KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
35endif 35endif
36 36
37ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
38KBUILD_CFLAGS +=-fstack-protector
39endif
40
37ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) 41ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
38KBUILD_CPPFLAGS += -mbig-endian 42KBUILD_CPPFLAGS += -mbig-endian
39AS += -EB 43AS += -EB
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
new file mode 100644
index 000000000000..de003327be97
--- /dev/null
+++ b/arch/arm/include/asm/stackprotector.h
@@ -0,0 +1,38 @@
1/*
2 * GCC stack protector support.
3 *
4 * Stack protector works by putting predefined pattern at the start of
5 * the stack frame and verifying that it hasn't been overwritten when
6 * returning from the function. The pattern is called stack canary
7 * and gcc expects it to be defined by a global variable called
8 * "__stack_chk_guard" on ARM. This unfortunately means that on SMP
9 * we cannot have a different canary value per task.
10 */
11
12#ifndef _ASM_STACKPROTECTOR_H
13#define _ASM_STACKPROTECTOR_H 1
14
15#include <linux/random.h>
16#include <linux/version.h>
17
18extern unsigned long __stack_chk_guard;
19
20/*
21 * Initialize the stackprotector canary value.
22 *
23 * NOTE: this must only be called from functions that never return,
24 * and it must always be inlined.
25 */
26static __always_inline void boot_init_stack_canary(void)
27{
28 unsigned long canary;
29
30 /* Try to get a semi random initial value. */
31 get_random_bytes(&canary, sizeof(canary));
32 canary ^= LINUX_VERSION_CODE;
33
34 current->stack_canary = canary;
35 __stack_chk_guard = current->stack_canary;
36}
37
38#endif /* _ASM_STACKPROTECTOR_H */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 1c6eb7ed9642..090ac9459da1 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -37,6 +37,12 @@
37#include <asm/stacktrace.h> 37#include <asm/stacktrace.h>
38#include <asm/mach/time.h> 38#include <asm/mach/time.h>
39 39
40#ifdef CONFIG_CC_STACKPROTECTOR
41#include <linux/stackprotector.h>
42unsigned long __stack_chk_guard __read_mostly;
43EXPORT_SYMBOL(__stack_chk_guard);
44#endif
45
40static const char *processor_modes[] = { 46static const char *processor_modes[] = {
41 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , 47 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
42 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", 48 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",