Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

zboot: fix stack protector in compressed boot phase

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>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Huacai Chen and committed by
Linus Torvalds
7bbaf27d 06dd3dfe

+3 -24
+1 -8
arch/arm/boot/compressed/misc.c
··· 128 128 error("Attempting division by 0!"); 129 129 } 130 130 131 - unsigned long __stack_chk_guard; 132 - 133 - void __stack_chk_guard_setup(void) 134 - { 135 - __stack_chk_guard = 0x000a0dff; 136 - } 131 + const unsigned long __stack_chk_guard = 0x000a0dff; 137 132 138 133 void __stack_chk_fail(void) 139 134 { ··· 144 149 int arch_id) 145 150 { 146 151 int ret; 147 - 148 - __stack_chk_guard_setup(); 149 152 150 153 output_data = (unsigned char *)output_start; 151 154 free_mem_ptr = free_mem_ptr_p;
+1 -8
arch/mips/boot/compressed/decompress.c
··· 76 76 #include "../../../../lib/decompress_unxz.c" 77 77 #endif 78 78 79 - unsigned long __stack_chk_guard; 80 - 81 - void __stack_chk_guard_setup(void) 82 - { 83 - __stack_chk_guard = 0x000a0dff; 84 - } 79 + const unsigned long __stack_chk_guard = 0x000a0dff; 85 80 86 81 void __stack_chk_fail(void) 87 82 { ··· 86 91 void decompress_kernel(unsigned long boot_heap_start) 87 92 { 88 93 unsigned long zimage_start, zimage_size; 89 - 90 - __stack_chk_guard_setup(); 91 94 92 95 zimage_start = (unsigned long)(&__image_begin); 93 96 zimage_size = (unsigned long)(&__image_end) -
+1 -8
arch/sh/boot/compressed/misc.c
··· 104 104 while(1); /* Halt */ 105 105 } 106 106 107 - unsigned long __stack_chk_guard; 108 - 109 - void __stack_chk_guard_setup(void) 110 - { 111 - __stack_chk_guard = 0x000a0dff; 112 - } 107 + const unsigned long __stack_chk_guard = 0x000a0dff; 113 108 114 109 void __stack_chk_fail(void) 115 110 { ··· 124 129 void decompress_kernel(void) 125 130 { 126 131 unsigned long output_addr; 127 - 128 - __stack_chk_guard_setup(); 129 132 130 133 #ifdef CONFIG_SUPERH64 131 134 output_addr = (CONFIG_MEMORY_START + 0x2000);