Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d920bb9 authored by Filippo Arcidiacono's avatar Filippo Arcidiacono Committed by Paul Mundt
Browse files

sh: initial stack protector support.



This implements basic -fstack-protector support, based on the early ARM
version in c743f380. 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: default avatarFilippo Arcidiacono <filippo.arcidiacono@st.com>
Reviewed-by: default avatarCarmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: default avatarStuart Menefy <stuart.menefy@st.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 932e9f35
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -685,6 +685,20 @@ config SECCOMP

	  If unsure, say N.

config CC_STACKPROTECTOR
	bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
	depends on SUPERH32 && EXPERIMENTAL
	help
	  This option turns on the -fstack-protector GCC feature. This
	  feature puts, at the beginning of functions, a canary value on
	  the stack just before the return address, and validates
	  the value just before actually returning.  Stack based buffer
	  overflows (that need to overwrite this return address) now also
	  overwrite the canary, which gets detected and the attack is then
	  neutralized via a kernel panic.

	  This feature requires gcc version 4.2 or above.

config SMP
	bool "Symmetric multi-processing support"
	depends on SYS_SUPPORTS_SMP
+4 −0
Original line number Diff line number Diff line
@@ -199,6 +199,10 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y)
  KBUILD_CFLAGS += -fasynchronous-unwind-tables
endif

ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
  KBUILD_CFLAGS += -fstack-protector
endif

libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)

+27 −0
Original line number Diff line number Diff line
#ifndef __ASM_SH_STACKPROTECTOR_H
#define __ASM_SH_STACKPROTECTOR_H

#include <linux/random.h>
#include <linux/version.h>

extern unsigned long __stack_chk_guard;

/*
 * Initialize the stackprotector canary value.
 *
 * NOTE: this must only be called from functions that never return,
 * and it must always be inlined.
 */
static __always_inline void boot_init_stack_canary(void)
{
	unsigned long canary;

	/* Try to get a semi random initial value. */
	get_random_bytes(&canary, sizeof(canary));
	canary ^= LINUX_VERSION_CODE;

	current->stack_canary = canary;
	__stack_chk_guard = current->stack_canary;
}

#endif /* __ASM_SH_STACKPROTECTOR_H */
+7 −0
Original line number Diff line number Diff line
@@ -2,10 +2,17 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/export.h>
#include <linux/stackprotector.h>

struct kmem_cache *task_xstate_cachep = NULL;
unsigned int xstate_size;

#ifdef CONFIG_CC_STACKPROTECTOR
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif

int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
	*dst = *src;
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/ftrace.h>
#include <linux/hw_breakpoint.h>
#include <linux/prefetch.h>
#include <linux/stackprotector.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/fpu.h>
@@ -220,6 +221,10 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
{
	struct thread_struct *next_t = &next->thread;

#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
	__stack_chk_guard = next->stack_canary;
#endif

	unlazy_fpu(prev, task_pt_regs(prev));

	/* we're going to use this soon, after a few expensive things */