1*09f33601SHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */
2*09f33601SHuacai Chen /*
3*09f33601SHuacai Chen  * GCC stack protector support.
4*09f33601SHuacai Chen  *
5*09f33601SHuacai Chen  * Stack protector works by putting predefined pattern at the start of
6*09f33601SHuacai Chen  * the stack frame and verifying that it hasn't been overwritten when
7*09f33601SHuacai Chen  * returning from the function. The pattern is called stack canary and
8*09f33601SHuacai Chen  * on LoongArch gcc expects it to be defined by a global variable called
9*09f33601SHuacai Chen  * "__stack_chk_guard".
10*09f33601SHuacai Chen  */
11*09f33601SHuacai Chen 
12*09f33601SHuacai Chen #ifndef _ASM_STACKPROTECTOR_H
13*09f33601SHuacai Chen #define _ASM_STACKPROTECTOR_H
14*09f33601SHuacai Chen 
15*09f33601SHuacai Chen #include <linux/random.h>
16*09f33601SHuacai Chen #include <linux/version.h>
17*09f33601SHuacai Chen 
18*09f33601SHuacai Chen extern unsigned long __stack_chk_guard;
19*09f33601SHuacai Chen 
20*09f33601SHuacai Chen /*
21*09f33601SHuacai Chen  * Initialize the stackprotector canary value.
22*09f33601SHuacai Chen  *
23*09f33601SHuacai Chen  * NOTE: this must only be called from functions that never return,
24*09f33601SHuacai Chen  * and it must always be inlined.
25*09f33601SHuacai Chen  */
boot_init_stack_canary(void)26*09f33601SHuacai Chen static __always_inline void boot_init_stack_canary(void)
27*09f33601SHuacai Chen {
28*09f33601SHuacai Chen 	unsigned long canary;
29*09f33601SHuacai Chen 
30*09f33601SHuacai Chen 	/* Try to get a semi random initial value. */
31*09f33601SHuacai Chen 	get_random_bytes(&canary, sizeof(canary));
32*09f33601SHuacai Chen 	canary ^= LINUX_VERSION_CODE;
33*09f33601SHuacai Chen 
34*09f33601SHuacai Chen 	current->stack_canary = canary;
35*09f33601SHuacai Chen 	__stack_chk_guard = current->stack_canary;
36*09f33601SHuacai Chen }
37*09f33601SHuacai Chen 
38*09f33601SHuacai Chen #endif	/* _ASM_STACKPROTECTOR_H */
39