summaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-12-27 11:19:07 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-27 11:19:07 -0800
commitc6f1b355d451680a45d63ce66cea67057c938a87 (patch)
tree413ed05d88e6a59d33a8b2034cfffdae1862e7b8 /arch/arm/include/asm
parentc06e9ef6918b1a6d183f1fef78ebc66f054a7b5a (diff)
parent189af4657186da08a2e79fb8e906cfd82b2ccddc (diff)
Merge tag 'gcc-plugins-v4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull gcc-plugins update from Kees Cook: "Both arm and arm64 are gaining per-task stack canaries (to match x86), but arm is being done with a gcc plugin, hence it going through the gcc-plugins tree. New gcc-plugin: - Enable per-task stack protector for ARM (Ard Biesheuvel)" * tag 'gcc-plugins-v4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: ARM: smp: add support for per-task stack canaries
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r--arch/arm/include/asm/stackprotector.h12
-rw-r--r--arch/arm/include/asm/thread_info.h3
2 files changed, 13 insertions, 2 deletions
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
index ef5f7b69443e..72a20c3a0a90 100644
--- a/arch/arm/include/asm/stackprotector.h
+++ b/arch/arm/include/asm/stackprotector.h
@@ -6,8 +6,10 @@
* the stack frame and verifying that it hasn't been overwritten when
* returning from the function. The pattern is called stack canary
* and gcc expects it to be defined by a global variable called
- * "__stack_chk_guard" on ARM. This unfortunately means that on SMP
- * we cannot have a different canary value per task.
+ * "__stack_chk_guard" on ARM. This prevents SMP systems from using a
+ * different value for each task unless we enable a GCC plugin that
+ * replaces these symbol references with references to each task's own
+ * value.
*/
#ifndef _ASM_STACKPROTECTOR_H
@@ -16,6 +18,8 @@
#include <linux/random.h>
#include <linux/version.h>
+#include <asm/thread_info.h>
+
extern unsigned long __stack_chk_guard;
/*
@@ -33,7 +37,11 @@ static __always_inline void boot_init_stack_canary(void)
canary ^= LINUX_VERSION_CODE;
current->stack_canary = canary;
+#ifndef CONFIG_STACKPROTECTOR_PER_TASK
__stack_chk_guard = current->stack_canary;
+#else
+ current_thread_info()->stack_canary = current->stack_canary;
+#endif
}
#endif /* _ASM_STACKPROTECTOR_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 8f55dc520a3e..286eb61c632b 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -53,6 +53,9 @@ struct thread_info {
struct task_struct *task; /* main task structure */
__u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */
+#ifdef CONFIG_STACKPROTECTOR_PER_TASK
+ unsigned long stack_canary;
+#endif
struct cpu_context_save cpu_context; /* cpu context */
__u32 syscall; /* syscall number */
__u8 used_cp[16]; /* thread used copro */