aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorFilippo Arcidiacono <filippo.arcidiacono@st.com>2012-04-19 02:45:57 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-04-19 02:45:57 -0400
commit5d920bb929a99446062a48cf90867bbca57b8e77 (patch)
treefdadebe0b0fe8906ffd81ad9f726430d6428a8f5 /arch/sh
parent932e9f352b5d685725076f21b237f7c7d804b29c (diff)
sh: initial stack protector support.
This implements basic -fstack-protector support, based on the early ARM version in c743f38013aeff58ef6252601e397b5ba281c633. The SMP case is limited to the initial canary value, while the UP case handles per-task granularity (limited to 32-bit sh until a new enough sh64 compiler manifests itself). Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com> Reviewed-by: Carmelo Amoroso <carmelo.amoroso@st.com> Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig14
-rw-r--r--arch/sh/Makefile4
-rw-r--r--arch/sh/include/asm/stackprotector.h27
-rw-r--r--arch/sh/kernel/process.c7
-rw-r--r--arch/sh/kernel/process_32.c5
5 files changed, 57 insertions, 0 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index ff9e033ce626..60ed3669979d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -685,6 +685,20 @@ config SECCOMP
685 685
686 If unsure, say N. 686 If unsure, say N.
687 687
688config CC_STACKPROTECTOR
689 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
690 depends on SUPERH32 && EXPERIMENTAL
691 help
692 This option turns on the -fstack-protector GCC feature. This
693 feature puts, at the beginning of functions, a canary value on
694 the stack just before the return address, and validates
695 the value just before actually returning. Stack based buffer
696 overflows (that need to overwrite this return address) now also
697 overwrite the canary, which gets detected and the attack is then
698 neutralized via a kernel panic.
699
700 This feature requires gcc version 4.2 or above.
701
688config SMP 702config SMP
689 bool "Symmetric multi-processing support" 703 bool "Symmetric multi-processing support"
690 depends on SYS_SUPPORTS_SMP 704 depends on SYS_SUPPORTS_SMP
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 3fc0f413777c..24875c8c1514 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -199,6 +199,10 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y)
199 KBUILD_CFLAGS += -fasynchronous-unwind-tables 199 KBUILD_CFLAGS += -fasynchronous-unwind-tables
200endif 200endif
201 201
202ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
203 KBUILD_CFLAGS += -fstack-protector
204endif
205
202libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) 206libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
203libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) 207libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
204 208
diff --git a/arch/sh/include/asm/stackprotector.h b/arch/sh/include/asm/stackprotector.h
new file mode 100644
index 000000000000..d9df3a76847c
--- /dev/null
+++ b/arch/sh/include/asm/stackprotector.h
@@ -0,0 +1,27 @@
1#ifndef __ASM_SH_STACKPROTECTOR_H
2#define __ASM_SH_STACKPROTECTOR_H
3
4#include <linux/random.h>
5#include <linux/version.h>
6
7extern unsigned long __stack_chk_guard;
8
9/*
10 * Initialize the stackprotector canary value.
11 *
12 * NOTE: this must only be called from functions that never return,
13 * and it must always be inlined.
14 */
15static __always_inline void boot_init_stack_canary(void)
16{
17 unsigned long canary;
18
19 /* Try to get a semi random initial value. */
20 get_random_bytes(&canary, sizeof(canary));
21 canary ^= LINUX_VERSION_CODE;
22
23 current->stack_canary = canary;
24 __stack_chk_guard = current->stack_canary;
25}
26
27#endif /* __ASM_SH_STACKPROTECTOR_H */
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 325f98b1736d..f3f03e4c785d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -2,10 +2,17 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/export.h>
6#include <linux/stackprotector.h>
5 7
6struct kmem_cache *task_xstate_cachep = NULL; 8struct kmem_cache *task_xstate_cachep = NULL;
7unsigned int xstate_size; 9unsigned int xstate_size;
8 10
11#ifdef CONFIG_CC_STACKPROTECTOR
12unsigned long __stack_chk_guard __read_mostly;
13EXPORT_SYMBOL(__stack_chk_guard);
14#endif
15
9int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 16int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
10{ 17{
11 *dst = *src; 18 *dst = *src;
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 94273aaf78c1..f78cc421e665 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -22,6 +22,7 @@
22#include <linux/ftrace.h> 22#include <linux/ftrace.h>
23#include <linux/hw_breakpoint.h> 23#include <linux/hw_breakpoint.h>
24#include <linux/prefetch.h> 24#include <linux/prefetch.h>
25#include <linux/stackprotector.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/mmu_context.h> 27#include <asm/mmu_context.h>
27#include <asm/fpu.h> 28#include <asm/fpu.h>
@@ -220,6 +221,10 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
220{ 221{
221 struct thread_struct *next_t = &next->thread; 222 struct thread_struct *next_t = &next->thread;
222 223
224#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
225 __stack_chk_guard = next->stack_canary;
226#endif
227
223 unlazy_fpu(prev, task_pt_regs(prev)); 228 unlazy_fpu(prev, task_pt_regs(prev));
224 229
225 /* we're going to use this soon, after a few expensive things */ 230 /* we're going to use this soon, after a few expensive things */