1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 260a5317fSTejun Heo /* 360a5317fSTejun Heo * GCC stack protector support. 460a5317fSTejun Heo * 580d47defSBrian Gerst * Stack protector works by putting a predefined pattern at the start of 660a5317fSTejun Heo * the stack frame and verifying that it hasn't been overwritten when 780d47defSBrian Gerst * returning from the function. The pattern is called the stack canary 880d47defSBrian Gerst * and is a unique value for each task. 960a5317fSTejun Heo */ 1060a5317fSTejun Heo 11b2b062b8SIngo Molnar #ifndef _ASM_STACKPROTECTOR_H 12b2b062b8SIngo Molnar #define _ASM_STACKPROTECTOR_H 1 13b2b062b8SIngo Molnar 14050e9baaSLinus Torvalds #ifdef CONFIG_STACKPROTECTOR 1576397f72STejun Heo 16b2b062b8SIngo Molnar #include <asm/tsc.h> 17947e76cdSBrian Gerst #include <asm/processor.h> 1876397f72STejun Heo #include <asm/percpu.h> 1960a5317fSTejun Heo #include <asm/desc.h> 20952f07ecSIngo Molnar 21952f07ecSIngo Molnar #include <linux/sched.h> 22b2b062b8SIngo Molnar 23*f3856cd3SBrian Gerst DECLARE_PER_CPU_CACHE_HOT(unsigned long, __stack_chk_guard); 2480d47defSBrian Gerst 25b2b062b8SIngo Molnar /* 26b2b062b8SIngo Molnar * Initialize the stackprotector canary value. 27b2b062b8SIngo Molnar * 28a9a3ed1eSBorislav Petkov * NOTE: this must only be called from functions that never return 29b2b062b8SIngo Molnar * and it must always be inlined. 30a9a3ed1eSBorislav Petkov * 31a9a3ed1eSBorislav Petkov * In addition, it should be called from a compilation unit for which 32a9a3ed1eSBorislav Petkov * stack protector is disabled. Alternatively, the caller should not end 33a9a3ed1eSBorislav Petkov * with a function call which gets tail-call optimized as that would 34a9a3ed1eSBorislav Petkov * lead to checking a modified canary value. 35b2b062b8SIngo Molnar */ boot_init_stack_canary(void)36b2b062b8SIngo Molnarstatic __always_inline void boot_init_stack_canary(void) 37b2b062b8SIngo Molnar { 38622754e8SJason A. Donenfeld unsigned long canary = get_random_canary(); 39b2b062b8SIngo Molnar 40b2b062b8SIngo Molnar current->stack_canary = canary; 413fb0fdb3SAndy Lutomirski this_cpu_write(__stack_chk_guard, canary); 4260a5317fSTejun Heo } 4360a5317fSTejun Heo cpu_init_stack_canary(int cpu,struct task_struct * idle)44c9a1ff31SBrian Gerststatic inline void cpu_init_stack_canary(int cpu, struct task_struct *idle) 45c9a1ff31SBrian Gerst { 463fb0fdb3SAndy Lutomirski per_cpu(__stack_chk_guard, cpu) = idle->stack_canary; 4760a5317fSTejun Heo } 4860a5317fSTejun Heo 49050e9baaSLinus Torvalds #else /* STACKPROTECTOR */ 5060a5317fSTejun Heo 5160a5317fSTejun Heo /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */ 5260a5317fSTejun Heo cpu_init_stack_canary(int cpu,struct task_struct * idle)53c9a1ff31SBrian Gerststatic inline void cpu_init_stack_canary(int cpu, struct task_struct *idle) 54c9a1ff31SBrian Gerst { } 55c9a1ff31SBrian Gerst 56050e9baaSLinus Torvalds #endif /* STACKPROTECTOR */ 5776397f72STejun Heo #endif /* _ASM_STACKPROTECTOR_H */ 58