1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * GCC stack protector support.
4  *
5  * Stack protector works by putting a predefined pattern at the start of
6  * the stack frame and verifying that it hasn't been overwritten when
7  * returning from the function.  The pattern is called the stack canary
8  * and is a unique value for each task.
9  */
10 
11 #ifndef _ASM_STACKPROTECTOR_H
12 #define _ASM_STACKPROTECTOR_H 1
13 
14 #ifdef CONFIG_STACKPROTECTOR
15 
16 #include <asm/tsc.h>
17 #include <asm/processor.h>
18 #include <asm/percpu.h>
19 #include <asm/desc.h>
20 
21 #include <linux/sched.h>
22 
23 DECLARE_PER_CPU_CACHE_HOT(unsigned long, __stack_chk_guard);
24 
25 /*
26  * Initialize the stackprotector canary value.
27  *
28  * NOTE: this must only be called from functions that never return
29  * and it must always be inlined.
30  *
31  * In addition, it should be called from a compilation unit for which
32  * stack protector is disabled. Alternatively, the caller should not end
33  * with a function call which gets tail-call optimized as that would
34  * lead to checking a modified canary value.
35  */
boot_init_stack_canary(void)36 static __always_inline void boot_init_stack_canary(void)
37 {
38 	unsigned long canary = get_random_canary();
39 
40 	current->stack_canary = canary;
41 	this_cpu_write(__stack_chk_guard, canary);
42 }
43 
cpu_init_stack_canary(int cpu,struct task_struct * idle)44 static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
45 {
46 	per_cpu(__stack_chk_guard, cpu) = idle->stack_canary;
47 }
48 
49 #else	/* STACKPROTECTOR */
50 
51 /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */
52 
cpu_init_stack_canary(int cpu,struct task_struct * idle)53 static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
54 { }
55 
56 #endif	/* STACKPROTECTOR */
57 #endif	/* _ASM_STACKPROTECTOR_H */
58