1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * GCC stack protector support. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Stack protector works by putting predefined pattern at the start of 6*4882a593Smuzhiyun * the stack frame and verifying that it hasn't been overwritten when 7*4882a593Smuzhiyun * returning from the function. The pattern is called stack canary 8*4882a593Smuzhiyun * and gcc expects it to be defined by a global variable called 9*4882a593Smuzhiyun * "__stack_chk_guard" on ARM. This prevents SMP systems from using a 10*4882a593Smuzhiyun * different value for each task unless we enable a GCC plugin that 11*4882a593Smuzhiyun * replaces these symbol references with references to each task's own 12*4882a593Smuzhiyun * value. 13*4882a593Smuzhiyun */ 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #ifndef _ASM_STACKPROTECTOR_H 16*4882a593Smuzhiyun #define _ASM_STACKPROTECTOR_H 1 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #include <linux/random.h> 19*4882a593Smuzhiyun #include <linux/version.h> 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #include <asm/thread_info.h> 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun extern unsigned long __stack_chk_guard; 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /* 26*4882a593Smuzhiyun * Initialize the stackprotector canary value. 27*4882a593Smuzhiyun * 28*4882a593Smuzhiyun * NOTE: this must only be called from functions that never return, 29*4882a593Smuzhiyun * and it must always be inlined. 30*4882a593Smuzhiyun */ boot_init_stack_canary(void)31*4882a593Smuzhiyunstatic __always_inline void boot_init_stack_canary(void) 32*4882a593Smuzhiyun { 33*4882a593Smuzhiyun unsigned long canary; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Try to get a semi random initial value. */ 36*4882a593Smuzhiyun get_random_bytes(&canary, sizeof(canary)); 37*4882a593Smuzhiyun canary ^= LINUX_VERSION_CODE; 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun current->stack_canary = canary; 40*4882a593Smuzhiyun #ifndef CONFIG_STACKPROTECTOR_PER_TASK 41*4882a593Smuzhiyun __stack_chk_guard = current->stack_canary; 42*4882a593Smuzhiyun #else 43*4882a593Smuzhiyun current_thread_info()->stack_canary = current->stack_canary; 44*4882a593Smuzhiyun #endif 45*4882a593Smuzhiyun } 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun #endif /* _ASM_STACKPROTECTOR_H */ 48