diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | arch/Kconfig | 51 | ||||
-rw-r--r-- | arch/arm/boot/compressed/misc.c | 14 |
3 files changed, 69 insertions, 4 deletions
@@ -596,12 +596,18 @@ KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) | |||
596 | endif | 596 | endif |
597 | 597 | ||
598 | # Handle stack protector mode. | 598 | # Handle stack protector mode. |
599 | ifdef CONFIG_CC_STACKPROTECTOR | 599 | ifdef CONFIG_CC_STACKPROTECTOR_REGULAR |
600 | stackp-flag := -fstack-protector | 600 | stackp-flag := -fstack-protector |
601 | ifeq ($(call cc-option, $(stackp-flag)),) | 601 | ifeq ($(call cc-option, $(stackp-flag)),) |
602 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR: \ | 602 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR: \ |
603 | -fstack-protector not supported by compiler)) | 603 | -fstack-protector not supported by compiler)) |
604 | endif | 604 | endif |
605 | else ifdef CONFIG_CC_STACKPROTECTOR_STRONG | ||
606 | stackp-flag := -fstack-protector-strong | ||
607 | ifeq ($(call cc-option, $(stackp-flag)),) | ||
608 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ | ||
609 | -fstack-protector-strong not supported by compiler) | ||
610 | endif | ||
605 | else | 611 | else |
606 | # Force off for distro compilers that enable stack protector by default. | 612 | # Force off for distro compilers that enable stack protector by default. |
607 | stackp-flag := $(call cc-option, -fno-stack-protector) | 613 | stackp-flag := $(call cc-option, -fno-stack-protector) |
diff --git a/arch/Kconfig b/arch/Kconfig index 24e026d83072..80bbb8ccd0d1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -344,10 +344,17 @@ config HAVE_CC_STACKPROTECTOR | |||
344 | - it has implemented a stack canary (e.g. __stack_chk_guard) | 344 | - it has implemented a stack canary (e.g. __stack_chk_guard) |
345 | 345 | ||
346 | config CC_STACKPROTECTOR | 346 | config CC_STACKPROTECTOR |
347 | bool "Enable -fstack-protector buffer overflow detection" | 347 | def_bool n |
348 | help | ||
349 | Set when a stack-protector mode is enabled, so that the build | ||
350 | can enable kernel-side support for the GCC feature. | ||
351 | |||
352 | choice | ||
353 | prompt "Stack Protector buffer overflow detection" | ||
348 | depends on HAVE_CC_STACKPROTECTOR | 354 | depends on HAVE_CC_STACKPROTECTOR |
355 | default CC_STACKPROTECTOR_NONE | ||
349 | help | 356 | help |
350 | This option turns on the -fstack-protector GCC feature. This | 357 | This option turns on the "stack-protector" GCC feature. This |
351 | feature puts, at the beginning of functions, a canary value on | 358 | feature puts, at the beginning of functions, a canary value on |
352 | the stack just before the return address, and validates | 359 | the stack just before the return address, and validates |
353 | the value just before actually returning. Stack based buffer | 360 | the value just before actually returning. Stack based buffer |
@@ -355,8 +362,46 @@ config CC_STACKPROTECTOR | |||
355 | overwrite the canary, which gets detected and the attack is then | 362 | overwrite the canary, which gets detected and the attack is then |
356 | neutralized via a kernel panic. | 363 | neutralized via a kernel panic. |
357 | 364 | ||
365 | config CC_STACKPROTECTOR_NONE | ||
366 | bool "None" | ||
367 | help | ||
368 | Disable "stack-protector" GCC feature. | ||
369 | |||
370 | config CC_STACKPROTECTOR_REGULAR | ||
371 | bool "Regular" | ||
372 | select CC_STACKPROTECTOR | ||
373 | help | ||
374 | Functions will have the stack-protector canary logic added if they | ||
375 | have an 8-byte or larger character array on the stack. | ||
376 | |||
358 | This feature requires gcc version 4.2 or above, or a distribution | 377 | This feature requires gcc version 4.2 or above, or a distribution |
359 | gcc with the feature backported. | 378 | gcc with the feature backported ("-fstack-protector"). |
379 | |||
380 | On an x86 "defconfig" build, this feature adds canary checks to | ||
381 | about 3% of all kernel functions, which increases kernel code size | ||
382 | by about 0.3%. | ||
383 | |||
384 | config CC_STACKPROTECTOR_STRONG | ||
385 | bool "Strong" | ||
386 | select CC_STACKPROTECTOR | ||
387 | help | ||
388 | Functions will have the stack-protector canary logic added in any | ||
389 | of the following conditions: | ||
390 | |||
391 | - local variable's address used as part of the right hand side of an | ||
392 | assignment or function argument | ||
393 | - local variable is an array (or union containing an array), | ||
394 | regardless of array type or length | ||
395 | - uses register local variables | ||
396 | |||
397 | This feature requires gcc version 4.9 or above, or a distribution | ||
398 | gcc with the feature backported ("-fstack-protector-strong"). | ||
399 | |||
400 | On an x86 "defconfig" build, this feature adds canary checks to | ||
401 | about 20% of all kernel functions, which increases the kernel code | ||
402 | size by about 2%. | ||
403 | |||
404 | endchoice | ||
360 | 405 | ||
361 | config HAVE_CONTEXT_TRACKING | 406 | config HAVE_CONTEXT_TRACKING |
362 | bool | 407 | bool |
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 31bd43b82095..d4f891f56996 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c | |||
@@ -127,6 +127,18 @@ asmlinkage void __div0(void) | |||
127 | error("Attempting division by 0!"); | 127 | error("Attempting division by 0!"); |
128 | } | 128 | } |
129 | 129 | ||
130 | unsigned long __stack_chk_guard; | ||
131 | |||
132 | void __stack_chk_guard_setup(void) | ||
133 | { | ||
134 | __stack_chk_guard = 0x000a0dff; | ||
135 | } | ||
136 | |||
137 | void __stack_chk_fail(void) | ||
138 | { | ||
139 | error("stack-protector: Kernel stack is corrupted\n"); | ||
140 | } | ||
141 | |||
130 | extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); | 142 | extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); |
131 | 143 | ||
132 | 144 | ||
@@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, | |||
137 | { | 149 | { |
138 | int ret; | 150 | int ret; |
139 | 151 | ||
152 | __stack_chk_guard_setup(); | ||
153 | |||
140 | output_data = (unsigned char *)output_start; | 154 | output_data = (unsigned char *)output_start; |
141 | free_mem_ptr = free_mem_ptr_p; | 155 | free_mem_ptr = free_mem_ptr_p; |
142 | free_mem_end_ptr = free_mem_ptr_end_p; | 156 | free_mem_end_ptr = free_mem_ptr_end_p; |