| From b3f1716cbaab44271c817f555cd4636c1137159a Mon Sep 17 00:00:00 2001 |
| From: Michael Ellerman <mpe@ellerman.id.au> |
| Date: Fri, 20 Mar 2020 14:21:16 +1100 |
| Subject: [PATCH] powerpc/64: Prevent stack protection in early boot |
| |
| commit 7053f80d96967d8e72e9f2a724bbfc3906ce2b07 upstream. |
| |
| The previous commit reduced the amount of code that is run before we |
| setup a paca. However there are still a few remaining functions that |
| run with no paca, or worse, with an arbitrary value in r13 that will |
| be used as a paca pointer. |
| |
| In particular the stack protector canary is stored in the paca, so if |
| stack protector is activated for any of these functions we will read |
| the stack canary from wherever r13 points. If r13 happens to point |
| outside of memory we will get a machine check / checkstop. |
| |
| For example if we modify initialise_paca() to trigger stack |
| protection, and then boot in the mambo simulator with r13 poisoned in |
| skiboot before calling the kernel: |
| |
| DEBUG: 19952232: (19952232): INSTRUCTION: PC=0xC0000000191FC1E8: [0x3C4C006D]: addis r2,r12,0x6D [fetch] |
| DEBUG: 19952236: (19952236): INSTRUCTION: PC=0xC00000001807EAD8: [0x7D8802A6]: mflr r12 [fetch] |
| FATAL ERROR: 19952276: (19952276): Check Stop for 0:0: Machine Check with ME bit of MSR off |
| DEBUG: 19952276: (19952276): INSTRUCTION: PC=0xC0000000191FCA7C: [0xE90D0CF8]: ld r8,0xCF8(r13) [Instruction Failed] |
| INFO: 19952276: (19952277): ** Execution stopped: Mambo Error, Machine Check Stop, ** |
| systemsim % bt |
| pc: 0xC0000000191FCA7C initialise_paca+0x54 |
| lr: 0xC0000000191FC22C early_setup+0x44 |
| stack:0x00000000198CBED0 0x0 +0x0 |
| stack:0x00000000198CBF00 0xC0000000191FC22C early_setup+0x44 |
| stack:0x00000000198CBF90 0x1801C968 +0x1801C968 |
| |
| So annotate the relevant functions to ensure stack protection is never |
| enabled for them. |
| |
| Fixes: 06ec27aea9fc ("powerpc/64: add stack protector support") |
| Cc: stable@vger.kernel.org # v4.20+ |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Link: https://lore.kernel.org/r/20200320032116.1024773-2-mpe@ellerman.id.au |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c |
| index 93203f87e44a..01800e5c4118 100644 |
| --- a/arch/powerpc/kernel/paca.c |
| +++ b/arch/powerpc/kernel/paca.c |
| @@ -134,7 +134,7 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit) |
| struct paca_struct **paca_ptrs __read_mostly; |
| EXPORT_SYMBOL(paca_ptrs); |
| |
| -void __init initialise_paca(struct paca_struct *new_paca, int cpu) |
| +void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu) |
| { |
| #ifdef CONFIG_PPC_PSERIES |
| new_paca->lppaca_ptr = NULL; |
| @@ -163,7 +163,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) |
| } |
| |
| /* Put the paca pointer into r13 and SPRG_PACA */ |
| -void setup_paca(struct paca_struct *new_paca) |
| +void __nostackprotector setup_paca(struct paca_struct *new_paca) |
| { |
| /* Setup r13 */ |
| local_paca = new_paca; |
| diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h |
| index c82577c4b15d..1b02d338a5f5 100644 |
| --- a/arch/powerpc/kernel/setup.h |
| +++ b/arch/powerpc/kernel/setup.h |
| @@ -8,6 +8,12 @@ |
| #ifndef __ARCH_POWERPC_KERNEL_SETUP_H |
| #define __ARCH_POWERPC_KERNEL_SETUP_H |
| |
| +#ifdef CONFIG_CC_IS_CLANG |
| +#define __nostackprotector |
| +#else |
| +#define __nostackprotector __attribute__((__optimize__("no-stack-protector"))) |
| +#endif |
| + |
| void initialize_cache_info(void); |
| void irqstack_early_init(void); |
| |
| diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c |
| index dcbb4f8a1476..d7ff21316cfa 100644 |
| --- a/arch/powerpc/kernel/setup_64.c |
| +++ b/arch/powerpc/kernel/setup_64.c |
| @@ -284,7 +284,7 @@ void __init record_spr_defaults(void) |
| * device-tree is not accessible via normal means at this point. |
| */ |
| |
| -void __init early_setup(unsigned long dt_ptr) |
| +void __init __nostackprotector early_setup(unsigned long dt_ptr) |
| { |
| static __initdata struct paca_struct boot_paca; |
| |
| -- |
| 2.7.4 |
| |