Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

LoongArch: Add RANDOMIZE_KSTACK_OFFSET support

Add support of kernel stack offset randomization while handling syscall,
the offset is defaultly limited by KSTACK_OFFSET_MAX().

In order to avoid triggering stack canaries (due to __builtin_alloca())
and slowing down the entry path, use __no_stack_protector attribute to
disable stack protector for do_syscall() at function level.

With this patch, the REPORT_STACK test show that:

`loongarch64 bits of stack entropy: 7`

Reviewed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

authored by

Jinjie Ruan and committed by
Huacai Chen
a0f7085f 08f417db

+22 -1
+1
arch/loongarch/Kconfig
··· 106 106 select HAVE_ARCH_KFENCE 107 107 select HAVE_ARCH_KGDB if PERF_EVENTS 108 108 select HAVE_ARCH_MMAP_RND_BITS if MMU 109 + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET 109 110 select HAVE_ARCH_SECCOMP 110 111 select HAVE_ARCH_SECCOMP_FILTER 111 112 select HAVE_ARCH_TRACEHOOK
+21 -1
arch/loongarch/kernel/syscall.c
··· 9 9 #include <linux/entry-common.h> 10 10 #include <linux/errno.h> 11 11 #include <linux/linkage.h> 12 + #include <linux/objtool.h> 13 + #include <linux/randomize_kstack.h> 12 14 #include <linux/syscalls.h> 13 15 #include <linux/unistd.h> 14 16 15 17 #include <asm/asm.h> 16 18 #include <asm/exception.h> 19 + #include <asm/loongarch.h> 17 20 #include <asm/signal.h> 18 21 #include <asm/switch_to.h> 19 22 #include <asm-generic/syscalls.h> ··· 42 39 typedef long (*sys_call_fn)(unsigned long, unsigned long, 43 40 unsigned long, unsigned long, unsigned long, unsigned long); 44 41 45 - void noinstr do_syscall(struct pt_regs *regs) 42 + void noinstr __no_stack_protector do_syscall(struct pt_regs *regs) 46 43 { 47 44 unsigned long nr; 48 45 sys_call_fn syscall_fn; ··· 58 55 59 56 nr = syscall_enter_from_user_mode(regs, nr); 60 57 58 + add_random_kstack_offset(); 59 + 61 60 if (nr < NR_syscalls) { 62 61 syscall_fn = sys_call_table[nr]; 63 62 regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6], 64 63 regs->regs[7], regs->regs[8], regs->regs[9]); 65 64 } 66 65 66 + /* 67 + * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 68 + * bits. The actual entropy will be further reduced by the compiler 69 + * when applying stack alignment constraints: 16-bytes (i.e. 4-bits) 70 + * aligned, which will remove the 4 low bits from any entropy chosen 71 + * here. 72 + * 73 + * The resulting 6 bits of entropy is seen in SP[9:4]. 74 + */ 75 + choose_random_kstack_offset(drdtime()); 76 + 67 77 syscall_exit_to_user_mode(regs); 68 78 } 79 + 80 + #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET 81 + STACK_FRAME_NON_STANDARD(do_syscall); 82 + #endif