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

xtensa: enable stack protector

The implementation is adopted from the ARM arch. GCC 7.3, 8 or newer is
required for building the xtensa kernel with SSP.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>

+61 -1
+1 -1
Documentation/features/debug/stackprotector/arch-support.txt
··· 35 35 | um: | TODO | 36 36 | unicore32: | TODO | 37 37 | x86: | ok | 38 - | xtensa: | TODO | 38 + | xtensa: | ok | 39 39 -----------------------
+1
arch/xtensa/Kconfig
··· 15 15 select GENERIC_IRQ_SHOW 16 16 select GENERIC_PCI_IOMAP 17 17 select GENERIC_SCHED_CLOCK 18 + select HAVE_CC_STACKPROTECTOR 18 19 select HAVE_DEBUG_KMEMLEAK 19 20 select HAVE_DMA_API_DEBUG 20 21 select HAVE_DMA_CONTIGUOUS
+4
arch/xtensa/boot/lib/Makefile
··· 15 15 CFLAGS_REMOVE_inffast.o = -pg 16 16 endif 17 17 18 + CFLAGS_REMOVE_inflate.o += -fstack-protector -fstack-protector-strong 19 + CFLAGS_REMOVE_zmem.o += -fstack-protector -fstack-protector-strong 20 + CFLAGS_REMOVE_inftrees.o += -fstack-protector -fstack-protector-strong 21 + CFLAGS_REMOVE_inffast.o += -fstack-protector -fstack-protector-strong 18 22 19 23 quiet_cmd_copy_zlib = COPY $@ 20 24 cmd_copy_zlib = cat $< > $@
+40
arch/xtensa/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 Xtensa. 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 */
+3
arch/xtensa/kernel/asm-offsets.c
··· 76 76 DEFINE(TASK_PID, offsetof (struct task_struct, pid)); 77 77 DEFINE(TASK_THREAD, offsetof (struct task_struct, thread)); 78 78 DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack)); 79 + #ifdef CONFIG_CC_STACKPROTECTOR 80 + DEFINE(TASK_STACK_CANARY, offsetof(struct task_struct, stack_canary)); 81 + #endif 79 82 DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct)); 80 83 81 84 /* offsets in thread_info struct */
+6
arch/xtensa/kernel/entry.S
··· 1971 1971 s32i a1, a2, THREAD_SP # save stack pointer 1972 1972 #endif 1973 1973 1974 + #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) 1975 + movi a6, __stack_chk_guard 1976 + l32i a8, a3, TASK_STACK_CANARY 1977 + s32i a8, a6, 0 1978 + #endif 1979 + 1974 1980 /* Disable ints while we manipulate the stack pointer. */ 1975 1981 1976 1982 irq_save a14, a3
+6
arch/xtensa/kernel/process.c
··· 58 58 EXPORT_SYMBOL(pm_power_off); 59 59 60 60 61 + #ifdef CONFIG_CC_STACKPROTECTOR 62 + #include <linux/stackprotector.h> 63 + unsigned long __stack_chk_guard __read_mostly; 64 + EXPORT_SYMBOL(__stack_chk_guard); 65 + #endif 66 + 61 67 #if XTENSA_HAVE_COPROCESSORS 62 68 63 69 void coprocessor_release_all(struct thread_info *ti)