Skip to content

Commit 09f3360

Browse files
committed
LoongArch: Add basic STACKPROTECTOR support
Add basic stack protector support similar to other architectures. A constant canary value is set at boot time, and with help of compiler's -fstack-protector we can detect stack corruption. Signed-off-by: Huacai Chen <[email protected]>
1 parent 7db54bf commit 09f3360

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

arch/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ config LOONGARCH
103103
select HAVE_REGS_AND_STACK_ACCESS_API
104104
select HAVE_RSEQ
105105
select HAVE_SETUP_PER_CPU_AREA if NUMA
106+
select HAVE_STACKPROTECTOR
106107
select HAVE_SYSCALL_TRACEPOINTS
107108
select HAVE_TIF_NOHZ
108109
select HAVE_VIRT_CPU_ACCOUNTING_GEN if !SMP
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* GCC stack protector support.
4+
*
5+
* Stack protector works by putting 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 stack canary and
8+
* on LoongArch gcc expects it to be defined by a global variable called
9+
* "__stack_chk_guard".
10+
*/
11+
12+
#ifndef _ASM_STACKPROTECTOR_H
13+
#define _ASM_STACKPROTECTOR_H
14+
15+
#include <linux/random.h>
16+
#include <linux/version.h>
17+
18+
extern unsigned long __stack_chk_guard;
19+
20+
/*
21+
* Initialize the stackprotector canary value.
22+
*
23+
* NOTE: this must only be called from functions that never return,
24+
* and it must always be inlined.
25+
*/
26+
static __always_inline void boot_init_stack_canary(void)
27+
{
28+
unsigned long canary;
29+
30+
/* Try to get a semi random initial value. */
31+
get_random_bytes(&canary, sizeof(canary));
32+
canary ^= LINUX_VERSION_CODE;
33+
34+
current->stack_canary = canary;
35+
__stack_chk_guard = current->stack_canary;
36+
}
37+
38+
#endif /* _ASM_STACKPROTECTOR_H */

arch/loongarch/kernel/asm-offsets.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ void output_task_defines(void)
6868
OFFSET(TASK_FLAGS, task_struct, flags);
6969
OFFSET(TASK_MM, task_struct, mm);
7070
OFFSET(TASK_PID, task_struct, pid);
71+
#if defined(CONFIG_STACKPROTECTOR)
72+
OFFSET(TASK_STACK_CANARY, task_struct, stack_canary);
73+
#endif
7174
DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
7275
BLANK();
7376
}

arch/loongarch/kernel/process.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@
4747
#include <asm/unwind.h>
4848
#include <asm/vdso.h>
4949

50+
#ifdef CONFIG_STACKPROTECTOR
51+
#include <linux/stackprotector.h>
52+
unsigned long __stack_chk_guard __read_mostly;
53+
EXPORT_SYMBOL(__stack_chk_guard);
54+
#endif
55+
5056
/*
5157
* Idle related variables and functions
5258
*/

arch/loongarch/kernel/switch.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ SYM_FUNC_START(__switch_to)
2323
stptr.d ra, a0, THREAD_REG01
2424
stptr.d a3, a0, THREAD_SCHED_RA
2525
stptr.d a4, a0, THREAD_SCHED_CFA
26+
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
27+
la t7, __stack_chk_guard
28+
LONG_L t8, a1, TASK_STACK_CANARY
29+
LONG_S t8, t7, 0
30+
#endif
2631
move tp, a2
2732
cpu_restore_nonscratch a1
2833

0 commit comments

Comments
 (0)