From dfbdcda280eb762bae2184145cc0702932d41798 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 18 Sep 2021 10:44:34 +0200 Subject: gcc-plugins: arm-ssp: Prepare for THREAD_INFO_IN_TASK support We will be enabling THREAD_INFO_IN_TASK support for ARM, which means that we can no longer load the stack canary value by masking the stack pointer and taking the copy that lives in thread_info. Instead, we will be able to load it from the task_struct directly, by using the TPIDRURO register which will hold the current task pointer when THREAD_INFO_IN_TASK is in effect. This is much more straight-forward, and allows us to declutter this code a bit while at it. Note that this means that ARMv6 (non-v6K) SMP systems can no longer use this feature, but those are quite rare to begin with, so this is a reasonable trade off. Reviewed-by: Kees Cook Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Amit Daniel Kachhap --- arch/arm/kernel/process.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/arm/kernel/process.c') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 0e2d3051741e..cd73c216b272 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -269,10 +269,6 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, thread_notify(THREAD_NOTIFY_COPY, thread); -#ifdef CONFIG_STACKPROTECTOR_PER_TASK - thread->stack_canary = p->stack_canary; -#endif - return 0; } -- cgit From 50596b7559bf226bb35ad55855ee979453ec06a1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 18 Sep 2021 10:44:37 +0200 Subject: ARM: smp: Store current pointer in TPIDRURO register if available Now that the user space TLS register is assigned on every return to user space, we can use it to keep the 'current' pointer while running in the kernel. This removes the need to access it via thread_info, which is located at the base of the stack, but will be moved out of there in a subsequent patch. Use the __builtin_thread_pointer() helper when available - this will help GCC understand that reloading the value within the same function is not necessary, even when using the per-task stack protector (which also generates accesses via the TLS register). For example, the generated code below loads TPIDRURO only once, and uses it to access both the stack canary and the preempt_count fields. : e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} ee1d 4f70 mrc 15, 0, r4, cr13, cr0, {3} 4606 mov r6, r0 b094 sub sp, #80 ; 0x50 f8d4 34e8 ldr.w r3, [r4, #1256] ; 0x4e8 <- stack canary 9313 str r3, [sp, #76] ; 0x4c f8d4 8004 ldr.w r8, [r4, #4] <- preempt count Co-developed-by: Keith Packard Signed-off-by: Keith Packard Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Amit Daniel Kachhap --- arch/arm/kernel/process.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/kernel/process.c') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index cd73c216b272..30428d756515 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -36,6 +36,10 @@ #include "signal.h" +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO +DEFINE_PER_CPU(struct task_struct *, __entry_task); +#endif + #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include unsigned long __stack_chk_guard __read_mostly; -- cgit