Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: initial stack protector support

Implements basic stack protector support based on ARM version in
c743f38013aeff58ef6252601e397b5ba281c633 , with Kconfig option,
constant canary value set at boot time, and script to check if
compiler actually supports stack protector.

Tested by creating a kernel module that writes past end of char[].

Signed-off-by: Gregory Fong <gregory.0xf0@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Filippo Arcidiacono <filippo.arcidiacono@st.com>
Cc: Carmelo Amoroso <carmelo.amoroso@st.com>
Patchwork: https://patchwork.linux-mips.org/patch/5448/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Gregory Fong and committed by
Ralf Baechle
36ecafc5 23df3415

+63
+13
arch/mips/Kconfig
··· 2367 2367 2368 2368 If unsure, say Y. Only embedded should say N here. 2369 2369 2370 + config CC_STACKPROTECTOR 2371 + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" 2372 + help 2373 + This option turns on the -fstack-protector GCC feature. This 2374 + feature puts, at the beginning of functions, a canary value on 2375 + the stack just before the return address, and validates 2376 + the value just before actually returning. Stack based buffer 2377 + overflows (that need to overwrite this return address) now also 2378 + overwrite the canary, which gets detected and the attack is then 2379 + neutralized via a kernel panic. 2380 + 2381 + This feature requires gcc version 4.2 or above. 2382 + 2370 2383 config USE_OF 2371 2384 bool 2372 2385 select OF
+4
arch/mips/Makefile
··· 227 227 228 228 LDFLAGS += -m $(ld-emul) 229 229 230 + ifdef CONFIG_CC_STACKPROTECTOR 231 + KBUILD_CFLAGS += -fstack-protector 232 + endif 233 + 230 234 ifdef CONFIG_MIPS 231 235 CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ 232 236 egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
+40
arch/mips/include/asm/stackprotector.h
··· 1 + /* 2 + * GCC stack protector support. 3 + * 4 + * (This is directly adopted from the ARM implementation) 5 + * 6 + * Stack protector works by putting predefined pattern at the start of 7 + * the stack frame and verifying that it hasn't been overwritten when 8 + * returning from the function. The pattern is called stack canary 9 + * and gcc expects it to be defined by a global variable called 10 + * "__stack_chk_guard" on MIPS. This unfortunately means that on SMP 11 + * we cannot have a different canary value per task. 12 + */ 13 + 14 + #ifndef _ASM_STACKPROTECTOR_H 15 + #define _ASM_STACKPROTECTOR_H 1 16 + 17 + #include <linux/random.h> 18 + #include <linux/version.h> 19 + 20 + extern unsigned long __stack_chk_guard; 21 + 22 + /* 23 + * Initialize the stackprotector canary value. 24 + * 25 + * NOTE: this must only be called from functions that never return, 26 + * and it must always be inlined. 27 + */ 28 + static __always_inline void boot_init_stack_canary(void) 29 + { 30 + unsigned long canary; 31 + 32 + /* Try to get a semi random initial value. */ 33 + get_random_bytes(&canary, sizeof(canary)); 34 + canary ^= LINUX_VERSION_CODE; 35 + 36 + current->stack_canary = canary; 37 + __stack_chk_guard = current->stack_canary; 38 + } 39 + 40 + #endif /* _ASM_STACKPROTECTOR_H */
+6
arch/mips/kernel/process.c
··· 201 201 return 1; 202 202 } 203 203 204 + #ifdef CONFIG_CC_STACKPROTECTOR 205 + #include <linux/stackprotector.h> 206 + unsigned long __stack_chk_guard __read_mostly; 207 + EXPORT_SYMBOL(__stack_chk_guard); 208 + #endif 209 + 204 210 /* 205 211 * 206 212 */