powerpc/64: add stack protector support
authorChristophe Leroy <christophe.leroy@c-s.fr>
Thu, 27 Sep 2018 07:05:55 +0000 (07:05 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 3 Oct 2018 05:40:03 +0000 (15:40 +1000)
On PPC64, as register r13 points to the paca_struct at all time,
this patch adds a copy of the canary there, which is copied at
task_switch.
That new canary is then used by using the following GCC options:
-mstack-protector-guard=tls
-mstack-protector-guard-reg=r13
-mstack-protector-guard-offset=offsetof(struct paca_struct, canary))

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/stackprotector.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/entry_64.S

index 3bcb05929931d07605f8447e804b2c273d88d946..602eea72362465ff34fb539f9b495e6a219410d6 100644 (file)
@@ -180,7 +180,7 @@ config PPC
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_CBPF_JIT                    if !PPC64
-       select HAVE_STACKPROTECTOR              if $(cc-option,-mstack-protector-guard=tls) && PPC32
+       select HAVE_STACKPROTECTOR              if $(cc-option,-mstack-protector-guard=tls)
        select HAVE_CONTEXT_TRACKING            if PPC64
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DEBUG_STACKOVERFLOW
index 45b8eb4d8fe7934c18b1be4414ce12a66b39395d..81552c7b46ebf31938848d20493548e6f9858847 100644 (file)
@@ -113,7 +113,11 @@ KBUILD_ARFLAGS     += --target=elf$(BITS)-$(GNUTARGET)
 endif
 
 cflags-$(CONFIG_STACKPROTECTOR)        += -mstack-protector-guard=tls
+ifdef CONFIG_PPC64
+cflags-$(CONFIG_STACKPROTECTOR)        += -mstack-protector-guard-reg=r13
+else
 cflags-$(CONFIG_STACKPROTECTOR)        += -mstack-protector-guard-reg=r2
+endif
 
 LDFLAGS_vmlinux-y := -Bstatic
 LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
@@ -411,8 +415,12 @@ ifdef CONFIG_STACKPROTECTOR
 prepare: stack_protector_prepare
 
 stack_protector_prepare: prepare0
+ifdef CONFIG_PPC64
+       $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
+else
        $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
 endif
+endif
 
 # Use the file '.tmp_gas_check' for binutils tests, as gas won't output
 # to stdout and these checks are run even on install targets.
index 7b6e23af38082fa7892befdc2f39371b1cbfc36d..c6d01f0aa898857ac5597d0fc7ecf750a344bbe6 100644 (file)
@@ -256,6 +256,9 @@ struct paca_struct {
        struct slb_entry *mce_faulty_slbs;
        u16 slb_save_cache_ptr;
 #endif /* CONFIG_PPC_BOOK3S_64 */
+#ifdef CONFIG_STACKPROTECTOR
+       unsigned long canary;
+#endif
 } ____cacheline_aligned;
 
 extern void copy_mm_to_paca(struct mm_struct *mm);
index d05d969c98c213041542f23e4953abf2ed984b9c..1c8460e235838ccfe7ee23c59a1854f438d5efa0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/version.h>
 #include <asm/reg.h>
 #include <asm/current.h>
+#include <asm/paca.h>
 
 /*
  * Initialize the stackprotector canary value.
@@ -29,6 +30,9 @@ static __always_inline void boot_init_stack_canary(void)
        canary &= CANARY_MASK;
 
        current->stack_canary = canary;
+#ifdef CONFIG_PPC64
+       get_paca()->canary = canary;
+#endif
 }
 
 #endif /* _ASM_STACKPROTECTOR_H */
index 9e9ee168e177e5a22a12e9b2446d1d509baf6d40..a6d70fd2e499245d20b6011a14b734794d175681 100644 (file)
@@ -81,6 +81,9 @@ int main(void)
        OFFSET(MM, task_struct, mm);
 #ifdef CONFIG_STACKPROTECTOR
        OFFSET(TASK_CANARY, task_struct, stack_canary);
+#ifdef CONFIG_PPC64
+       OFFSET(PACA_CANARY, paca_struct, canary);
+#endif
 #endif
        OFFSET(MMCONTEXTID, mm_struct, context.id);
 #ifdef CONFIG_PPC64
index 77a888bfcb536aec2048d05b89bffbe3a59900a6..573fa879d785b64028581a4b4a76a3e5309d3bfa 100644 (file)
@@ -624,6 +624,10 @@ _GLOBAL(_switch)
 
        addi    r6,r4,-THREAD   /* Convert THREAD to 'current' */
        std     r6,PACACURRENT(r13)     /* Set new 'current' */
+#if defined(CONFIG_STACKPROTECTOR)
+       ld      r6, TASK_CANARY(r6)
+       std     r6, PACA_CANARY(r13)
+#endif
 
        ld      r8,KSP(r4)      /* new stack pointer */
 #ifdef CONFIG_PPC_BOOK3S_64