| From: Huacai Chen <chenhc@lemote.com> |
| Date: Thu, 5 Apr 2018 16:18:18 -0700 |
| Subject: zboot: fix stack protector in compressed boot phase |
| |
| commit 7bbaf27d9c83037b6e60a818e57bdbedf6bc15be upstream. |
| |
| Calling __stack_chk_guard_setup() in decompress_kernel() is too late |
| that stack checking always fails for decompress_kernel() itself. So |
| remove __stack_chk_guard_setup() and initialize __stack_chk_guard before |
| we call decompress_kernel(). |
| |
| Original code comes from ARM but also used for MIPS and SH, so fix them |
| together. If without this fix, compressed booting of these archs will |
| fail because stack checking is enabled by default (>=4.16). |
| |
| Link: http://lkml.kernel.org/r/1522226933-29317-1-git-send-email-chenhc@lemote.com |
| Fixes: 8779657d29c0 ("stackprotector: Introduce CONFIG_CC_STACKPROTECTOR_STRONG") |
| Signed-off-by: Huacai Chen <chenhc@lemote.com> |
| Acked-by: James Hogan <jhogan@kernel.org> |
| Acked-by: Kees Cook <keescook@chromium.org> |
| Acked-by: Rich Felker <dalias@libc.org> |
| Cc: Ralf Baechle <ralf@linux-mips.org> |
| Cc: Russell King <linux@arm.linux.org.uk> |
| Cc: Yoshinori Sato <ysato@users.sourceforge.jp> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| [bwh: Backported to 3.16: Only ARM has this problem] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/arch/arm/boot/compressed/misc.c |
| +++ b/arch/arm/boot/compressed/misc.c |
| @@ -127,12 +127,7 @@ asmlinkage void __div0(void) |
| error("Attempting division by 0!"); |
| } |
| |
| -unsigned long __stack_chk_guard; |
| - |
| -void __stack_chk_guard_setup(void) |
| -{ |
| - __stack_chk_guard = 0x000a0dff; |
| -} |
| +const unsigned long __stack_chk_guard = 0x000a0dff; |
| |
| void __stack_chk_fail(void) |
| { |
| @@ -149,8 +144,6 @@ decompress_kernel(unsigned long output_s |
| { |
| int ret; |
| |
| - __stack_chk_guard_setup(); |
| - |
| output_data = (unsigned char *)output_start; |
| free_mem_ptr = free_mem_ptr_p; |
| free_mem_end_ptr = free_mem_ptr_end_p; |