[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20250424073251.81693-1-youling.tang@linux.dev>
Date: Thu, 24 Apr 2025 15:32:51 +0800
From: Youling Tang <youling.tang@...ux.dev>
To: Huacai Chen <chenhuacai@...nel.org>
Cc: Ard Biesheuvel <ardb@...nel.org>,
loongarch@...ts.linux.dev,
linux-kernel@...r.kernel.org,
linux-efi@...r.kernel.org,
youling.tang@...ux.dev,
Youling Tang <tangyouling@...inos.cn>
Subject: [PATCH v2] LoongArch: Enable HAVE_ARCH_STACKLEAK
From: Youling Tang <tangyouling@...inos.cn>
Add support for the stackleak feature. It initialize the stack with the
poison value before returning from system calls which improves the kernel
security.
At the same time, disables the plugin in EFI stub code because EFI stub
is out of scope for the protection.
Tested on 3A5000 (enable CONFIG_GCC_PLUGIN_STACKLEAK and CONFIG_LKDTM):
# echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT
# dmesg
lkdtm: Performing direct entry STACKLEAK_ERASING
lkdtm: stackleak stack usage:
high offset: 320 bytes
current: 448 bytes
lowest: 1264 bytes
tracked: 1264 bytes
untracked: 208 bytes
poisoned: 14528 bytes
low offset: 64 bytes
lkdtm: OK: the rest of the thread stack is properly erased
Signed-off-by: Youling Tang <tangyouling@...inos.cn>
---
v2:
* Make on_thread_stack() __always_inline.
* Move the STACKLEAK_ERASE macro to the stackframe.h file.
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/entry-common.h | 8 +-------
arch/loongarch/include/asm/stackframe.h | 6 ++++++
arch/loongarch/include/asm/stacktrace.h | 5 +++++
arch/loongarch/kernel/entry.S | 3 +++
drivers/firmware/efi/libstub/Makefile | 2 +-
6 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 067c0b994648..3a6bfcab2dde 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -122,6 +122,7 @@ config LOONGARCH
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP
select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_STACKLEAK
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
diff --git a/arch/loongarch/include/asm/entry-common.h b/arch/loongarch/include/asm/entry-common.h
index 0fe2a098ded9..a7a6af490f86 100644
--- a/arch/loongarch/include/asm/entry-common.h
+++ b/arch/loongarch/include/asm/entry-common.h
@@ -2,12 +2,6 @@
#ifndef ARCH_LOONGARCH_ENTRY_COMMON_H
#define ARCH_LOONGARCH_ENTRY_COMMON_H
-#include <linux/sched.h>
-#include <linux/processor.h>
-
-static inline bool on_thread_stack(void)
-{
- return !(((unsigned long)(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE - 1));
-}
+#include <asm/stacktrace.h>
#endif
diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
index 66736837085b..c37455bca29b 100644
--- a/arch/loongarch/include/asm/stackframe.h
+++ b/arch/loongarch/include/asm/stackframe.h
@@ -243,4 +243,10 @@
RESTORE_SP_AND_RET \docfi
.endm
+ .macro STACKLEAK_ERASE
+#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
+ bl stackleak_erase_on_task_stack
+#endif
+ .endm
+
#endif /* _ASM_STACKFRAME_H */
diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
index fc8b64773794..5c8be156567c 100644
--- a/arch/loongarch/include/asm/stacktrace.h
+++ b/arch/loongarch/include/asm/stacktrace.h
@@ -31,6 +31,11 @@ bool in_irq_stack(unsigned long stack, struct stack_info *info);
bool in_task_stack(unsigned long stack, struct task_struct *task, struct stack_info *info);
int get_stack_info(unsigned long stack, struct task_struct *task, struct stack_info *info);
+static __always_inline bool on_thread_stack(void)
+{
+ return !(((unsigned long)(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE - 1));
+}
+
#define STR_LONG_L __stringify(LONG_L)
#define STR_LONG_S __stringify(LONG_S)
#define STR_LONGSIZE __stringify(LONGSIZE)
diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S
index 48e7e34e355e..77f6fb9146a2 100644
--- a/arch/loongarch/kernel/entry.S
+++ b/arch/loongarch/kernel/entry.S
@@ -73,6 +73,7 @@ SYM_CODE_START(handle_syscall)
move a0, sp
bl do_syscall
+ STACKLEAK_ERASE
RESTORE_ALL_AND_RET
SYM_CODE_END(handle_syscall)
_ASM_NOKPROBE(handle_syscall)
@@ -82,6 +83,7 @@ SYM_CODE_START(ret_from_fork)
bl schedule_tail # a0 = struct task_struct *prev
move a0, sp
bl syscall_exit_to_user_mode
+ STACKLEAK_ERASE
RESTORE_STATIC
RESTORE_SOME
RESTORE_SP_AND_RET
@@ -94,6 +96,7 @@ SYM_CODE_START(ret_from_kernel_thread)
jirl ra, s0, 0
move a0, sp
bl syscall_exit_to_user_mode
+ STACKLEAK_ERASE
RESTORE_STATIC
RESTORE_SOME
RESTORE_SP_AND_RET
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index d23a1b9fed75..b97981d63d2f 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -31,7 +31,7 @@ cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
$(DISABLE_STACKLEAK_PLUGIN)
cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE -mno-relax \
$(DISABLE_STACKLEAK_PLUGIN)
-cflags-$(CONFIG_LOONGARCH) += -fpie
+cflags-$(CONFIG_LOONGARCH) += -fpie $(DISABLE_STACKLEAK_PLUGIN)
cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt
--
2.38.1
Powered by blists - more mailing lists