* [PATCH v3] provide -fstack-protector-strong build option @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-kernel Cc: Michal Marek, Russell King, Ralf Baechle, Paul Mundt, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton, James Hogan, Stephen Rothwell, Shawn Guo, x86, linux-kbuild, linux-arm-kernel, linux-mips, linux-sh, keescook This reorganizes the build options for CONFIG_CC_STACKPROTECTOR so that the new CONFIG_CC_STACKPROTECTOR_STRONG can be used when building with a compiler that supports it. -Kees ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3] provide -fstack-protector-strong build option @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel This reorganizes the build options for CONFIG_CC_STACKPROTECTOR so that the new CONFIG_CC_STACKPROTECTOR_STRONG can be used when building with a compiler that supports it. -Kees ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3] provide -fstack-protector-strong build option @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel This reorganizes the build options for CONFIG_CC_STACKPROTECTOR so that the new CONFIG_CC_STACKPROTECTOR_STRONG can be used when building with a compiler that supports it. -Kees ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/2] create HAVE_CC_STACKPROTECTOR for centralized use 2013-12-17 22:43 ` Kees Cook (?) @ 2013-12-17 22:43 ` Kees Cook -1 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-kernel Cc: Michal Marek, Russell King, Ralf Baechle, Paul Mundt, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton, James Hogan, Stephen Rothwell, Shawn Guo, x86, linux-kbuild, linux-arm-kernel, linux-mips, linux-sh, keescook Instead of duplicating the CC_STACKPROTECTOR Kconfig and Makefile logic in each architecture, switch to using HAVE_CC_STACKPROTECTOR and keep everything in one place. This retains the x86-specific bug verification scripts. Signed-off-by: Kees Cook <keescook@chromium.org> --- Makefile | 14 +++++++++++--- arch/Kconfig | 22 ++++++++++++++++++++++ arch/arm/Kconfig | 13 +------------ arch/arm/Makefile | 4 ---- arch/mips/Kconfig | 14 +------------- arch/mips/Makefile | 4 ---- arch/sh/Kconfig | 15 +-------------- arch/sh/Makefile | 4 ---- arch/x86/Kconfig | 17 +---------------- arch/x86/Makefile | 8 +++----- 10 files changed, 40 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 858a147fd836..27ed3ff7cf4c 100644 --- a/Makefile +++ b/Makefile @@ -595,10 +595,18 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -# Force gcc to behave correct even for buggy distributions -ifndef CONFIG_CC_STACKPROTECTOR -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) +# Handle stack protector mode. +ifdef CONFIG_CC_STACKPROTECTOR + stackp-flag := $(call cc-option, -fstack-protector) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ + -fstack-protector not supported by compiler)) + endif +else + # Force off for distro compilers that enable stack protector by default. + stackp-flag := $(call cc-option, -fno-stack-protector) endif +KBUILD_CFLAGS += $(stackp-flag) # This warning generated too much noise in a regular build. # Use make W=1 to enable this warning (see scripts/Makefile.build) diff --git a/arch/Kconfig b/arch/Kconfig index f1cf895c040f..24e026d83072 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -336,6 +336,28 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_CC_STACKPROTECTOR + bool + help + An arch should select this symbol if: + - its compiler supports the -fstack-protector option + - it has implemented a stack canary (e.g. __stack_chk_guard) + +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection" + depends on HAVE_CC_STACKPROTECTOR + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + + This feature requires gcc version 4.2 or above, or a distribution + gcc with the feature backported. + config HAVE_CONTEXT_TRACKING bool help diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f1a7eee953..9c909fc29272 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -30,6 +30,7 @@ config ARM select HAVE_BPF_JIT select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT + select HAVE_CC_STACKPROTECTOR select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS @@ -1856,18 +1857,6 @@ config SECCOMP and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - This feature requires gcc version 4.2 or above. - config SWIOTLB def_bool y diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c99b1086d83d..55b4255ad6ed 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -40,10 +40,6 @@ ifeq ($(CONFIG_FRAME_POINTER),y) KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) -KBUILD_CFLAGS +=-fstack-protector -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 650de3976e7a..c93d92beb3d6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -47,6 +47,7 @@ config MIPS select MODULES_USE_ELF_RELA if MODULES && 64BIT select CLONE_BACKWARDS select HAVE_DEBUG_STACKOVERFLOW + select HAVE_CC_STACKPROTECTOR menu "Machine selection" @@ -2322,19 +2323,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config USE_OF bool select OF diff --git a/arch/mips/Makefile b/arch/mips/Makefile index de300b993607..efe50787cd89 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -232,10 +232,6 @@ bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ LDFLAGS += -m $(ld-emul) -ifdef CONFIG_CC_STACKPROTECTOR - KBUILD_CFLAGS += -fstack-protector -endif - ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9b0979f4df7a..ce298317a73e 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -66,6 +66,7 @@ config SUPERH32 select PERF_EVENTS select ARCH_HIBERNATION_POSSIBLE if MMU select SPARSE_IRQ + select HAVE_CC_STACKPROTECTOR config SUPERH64 def_bool ARCH = "sh64" @@ -695,20 +696,6 @@ config SECCOMP If unsure, say N. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on SUPERH32 - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/Makefile b/arch/sh/Makefile index aed701c7b11b..d4d16e4be07c 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -199,10 +199,6 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y) KBUILD_CFLAGS += -fasynchronous-unwind-tables endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) - KBUILD_CFLAGS += -fstack-protector -endif - libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e903c71f7e69..4a814e6c526b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -124,6 +124,7 @@ config X86 select RTC_LIB select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 + select HAVE_CC_STACKPROTECTOR config INSTRUCTION_DECODER def_bool y @@ -1616,22 +1617,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" - ---help--- - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is - ignored. (and a warning is printed during bootup) - source kernel/Kconfig.hz config KEXEC diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 57d021507120..66d126ab9942 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -89,13 +89,11 @@ else KBUILD_CFLAGS += -maccumulate-outgoing-args endif +# Make sure compiler does not have buggy stackprotector support. ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh - ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) - stackp-y := -fstack-protector - KBUILD_CFLAGS += $(stackp-y) - else - $(warning stack protector enabled but no compiler support) + ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) + $(error stack protector enabled but compiler support is broken) endif endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 1/2] create HAVE_CC_STACKPROTECTOR for centralized use @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel Instead of duplicating the CC_STACKPROTECTOR Kconfig and Makefile logic in each architecture, switch to using HAVE_CC_STACKPROTECTOR and keep everything in one place. This retains the x86-specific bug verification scripts. Signed-off-by: Kees Cook <keescook@chromium.org> --- Makefile | 14 +++++++++++--- arch/Kconfig | 22 ++++++++++++++++++++++ arch/arm/Kconfig | 13 +------------ arch/arm/Makefile | 4 ---- arch/mips/Kconfig | 14 +------------- arch/mips/Makefile | 4 ---- arch/sh/Kconfig | 15 +-------------- arch/sh/Makefile | 4 ---- arch/x86/Kconfig | 17 +---------------- arch/x86/Makefile | 8 +++----- 10 files changed, 40 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 858a147fd836..27ed3ff7cf4c 100644 --- a/Makefile +++ b/Makefile @@ -595,10 +595,18 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -# Force gcc to behave correct even for buggy distributions -ifndef CONFIG_CC_STACKPROTECTOR -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) +# Handle stack protector mode. +ifdef CONFIG_CC_STACKPROTECTOR + stackp-flag := $(call cc-option, -fstack-protector) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ + -fstack-protector not supported by compiler)) + endif +else + # Force off for distro compilers that enable stack protector by default. + stackp-flag := $(call cc-option, -fno-stack-protector) endif +KBUILD_CFLAGS += $(stackp-flag) # This warning generated too much noise in a regular build. # Use make W=1 to enable this warning (see scripts/Makefile.build) diff --git a/arch/Kconfig b/arch/Kconfig index f1cf895c040f..24e026d83072 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -336,6 +336,28 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_CC_STACKPROTECTOR + bool + help + An arch should select this symbol if: + - its compiler supports the -fstack-protector option + - it has implemented a stack canary (e.g. __stack_chk_guard) + +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection" + depends on HAVE_CC_STACKPROTECTOR + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + + This feature requires gcc version 4.2 or above, or a distribution + gcc with the feature backported. + config HAVE_CONTEXT_TRACKING bool help diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f1a7eee953..9c909fc29272 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -30,6 +30,7 @@ config ARM select HAVE_BPF_JIT select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT + select HAVE_CC_STACKPROTECTOR select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS @@ -1856,18 +1857,6 @@ config SECCOMP and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - This feature requires gcc version 4.2 or above. - config SWIOTLB def_bool y diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c99b1086d83d..55b4255ad6ed 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -40,10 +40,6 @@ ifeq ($(CONFIG_FRAME_POINTER),y) KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) -KBUILD_CFLAGS +=-fstack-protector -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 650de3976e7a..c93d92beb3d6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -47,6 +47,7 @@ config MIPS select MODULES_USE_ELF_RELA if MODULES && 64BIT select CLONE_BACKWARDS select HAVE_DEBUG_STACKOVERFLOW + select HAVE_CC_STACKPROTECTOR menu "Machine selection" @@ -2322,19 +2323,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config USE_OF bool select OF diff --git a/arch/mips/Makefile b/arch/mips/Makefile index de300b993607..efe50787cd89 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -232,10 +232,6 @@ bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ LDFLAGS += -m $(ld-emul) -ifdef CONFIG_CC_STACKPROTECTOR - KBUILD_CFLAGS += -fstack-protector -endif - ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9b0979f4df7a..ce298317a73e 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -66,6 +66,7 @@ config SUPERH32 select PERF_EVENTS select ARCH_HIBERNATION_POSSIBLE if MMU select SPARSE_IRQ + select HAVE_CC_STACKPROTECTOR config SUPERH64 def_bool ARCH = "sh64" @@ -695,20 +696,6 @@ config SECCOMP If unsure, say N. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on SUPERH32 - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/Makefile b/arch/sh/Makefile index aed701c7b11b..d4d16e4be07c 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -199,10 +199,6 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y) KBUILD_CFLAGS += -fasynchronous-unwind-tables endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) - KBUILD_CFLAGS += -fstack-protector -endif - libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e903c71f7e69..4a814e6c526b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -124,6 +124,7 @@ config X86 select RTC_LIB select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 + select HAVE_CC_STACKPROTECTOR config INSTRUCTION_DECODER def_bool y @@ -1616,22 +1617,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" - ---help--- - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is - ignored. (and a warning is printed during bootup) - source kernel/Kconfig.hz config KEXEC diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 57d021507120..66d126ab9942 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -89,13 +89,11 @@ else KBUILD_CFLAGS += -maccumulate-outgoing-args endif +# Make sure compiler does not have buggy stackprotector support. ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh - ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) - stackp-y := -fstack-protector - KBUILD_CFLAGS += $(stackp-y) - else - $(warning stack protector enabled but no compiler support) + ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) + $(error stack protector enabled but compiler support is broken) endif endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 1/2] create HAVE_CC_STACKPROTECTOR for centralized use @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel Instead of duplicating the CC_STACKPROTECTOR Kconfig and Makefile logic in each architecture, switch to using HAVE_CC_STACKPROTECTOR and keep everything in one place. This retains the x86-specific bug verification scripts. Signed-off-by: Kees Cook <keescook@chromium.org> --- Makefile | 14 +++++++++++--- arch/Kconfig | 22 ++++++++++++++++++++++ arch/arm/Kconfig | 13 +------------ arch/arm/Makefile | 4 ---- arch/mips/Kconfig | 14 +------------- arch/mips/Makefile | 4 ---- arch/sh/Kconfig | 15 +-------------- arch/sh/Makefile | 4 ---- arch/x86/Kconfig | 17 +---------------- arch/x86/Makefile | 8 +++----- 10 files changed, 40 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 858a147fd836..27ed3ff7cf4c 100644 --- a/Makefile +++ b/Makefile @@ -595,10 +595,18 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -# Force gcc to behave correct even for buggy distributions -ifndef CONFIG_CC_STACKPROTECTOR -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) +# Handle stack protector mode. +ifdef CONFIG_CC_STACKPROTECTOR + stackp-flag := $(call cc-option, -fstack-protector) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ + -fstack-protector not supported by compiler)) + endif +else + # Force off for distro compilers that enable stack protector by default. + stackp-flag := $(call cc-option, -fno-stack-protector) endif +KBUILD_CFLAGS += $(stackp-flag) # This warning generated too much noise in a regular build. # Use make W=1 to enable this warning (see scripts/Makefile.build) diff --git a/arch/Kconfig b/arch/Kconfig index f1cf895c040f..24e026d83072 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -336,6 +336,28 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_CC_STACKPROTECTOR + bool + help + An arch should select this symbol if: + - its compiler supports the -fstack-protector option + - it has implemented a stack canary (e.g. __stack_chk_guard) + +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection" + depends on HAVE_CC_STACKPROTECTOR + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + + This feature requires gcc version 4.2 or above, or a distribution + gcc with the feature backported. + config HAVE_CONTEXT_TRACKING bool help diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f1a7eee953..9c909fc29272 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -30,6 +30,7 @@ config ARM select HAVE_BPF_JIT select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT + select HAVE_CC_STACKPROTECTOR select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS @@ -1856,18 +1857,6 @@ config SECCOMP and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - This feature requires gcc version 4.2 or above. - config SWIOTLB def_bool y diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c99b1086d83d..55b4255ad6ed 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -40,10 +40,6 @@ ifeq ($(CONFIG_FRAME_POINTER),y) KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) -KBUILD_CFLAGS +=-fstack-protector -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 650de3976e7a..c93d92beb3d6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -47,6 +47,7 @@ config MIPS select MODULES_USE_ELF_RELA if MODULES && 64BIT select CLONE_BACKWARDS select HAVE_DEBUG_STACKOVERFLOW + select HAVE_CC_STACKPROTECTOR menu "Machine selection" @@ -2322,19 +2323,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config USE_OF bool select OF diff --git a/arch/mips/Makefile b/arch/mips/Makefile index de300b993607..efe50787cd89 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -232,10 +232,6 @@ bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ LDFLAGS += -m $(ld-emul) -ifdef CONFIG_CC_STACKPROTECTOR - KBUILD_CFLAGS += -fstack-protector -endif - ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9b0979f4df7a..ce298317a73e 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -66,6 +66,7 @@ config SUPERH32 select PERF_EVENTS select ARCH_HIBERNATION_POSSIBLE if MMU select SPARSE_IRQ + select HAVE_CC_STACKPROTECTOR config SUPERH64 def_bool ARCH = "sh64" @@ -695,20 +696,6 @@ config SECCOMP If unsure, say N. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on SUPERH32 - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above. - config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/Makefile b/arch/sh/Makefile index aed701c7b11b..d4d16e4be07c 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -199,10 +199,6 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y) KBUILD_CFLAGS += -fasynchronous-unwind-tables endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) - KBUILD_CFLAGS += -fstack-protector -endif - libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e903c71f7e69..4a814e6c526b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -124,6 +124,7 @@ config X86 select RTC_LIB select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 + select HAVE_CC_STACKPROTECTOR config INSTRUCTION_DECODER def_bool y @@ -1616,22 +1617,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" - ---help--- - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is - ignored. (and a warning is printed during bootup) - source kernel/Kconfig.hz config KEXEC diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 57d021507120..66d126ab9942 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -89,13 +89,11 @@ else KBUILD_CFLAGS += -maccumulate-outgoing-args endif +# Make sure compiler does not have buggy stackprotector support. ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh - ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) - stackp-y := -fstack-protector - KBUILD_CFLAGS += $(stackp-y) - else - $(warning stack protector enabled but no compiler support) + ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) + $(error stack protector enabled but compiler support is broken) endif endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 2/2] provide -fstack-protector-strong build option 2013-12-17 22:43 ` Kees Cook (?) @ 2013-12-17 22:43 ` Kees Cook -1 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-kernel Cc: Michal Marek, Russell King, Ralf Baechle, Paul Mundt, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton, James Hogan, Stephen Rothwell, Shawn Guo, x86, linux-kbuild, linux-arm-kernel, linux-mips, linux-sh, keescook This changes the stack protector config option into a choice of "None", "Regular", and "Strong". For "Strong", the kernel is built with -fstack-protector-strong (gcc 4.9 and later). This options increases the coverage of the stack protector without the heavy performance hit of -fstack-protector-all. For reference, the stack protector options available in gcc are: -fstack-protector-all: Adds the stack-canary saving prefix and stack-canary checking suffix to _all_ function entry and exit. Results in substantial use of stack space for saving the canary for deep stack users (e.g. historically xfs), and measurable (though shockingly still low) performance hit due to all the saving/checking. Really not suitable for sane systems, and was entirely removed as an option from the kernel many years ago. -fstack-protector: Adds the canary save/check to functions that define an 8 (--param=ssp-buffer-size=N, N=8 by default) or more byte local char array. Traditionally, stack overflows happened with string-based manipulations, so this was a way to find those functions. Very few total functions actually get the canary; no measurable performance or size overhead. -fstack-protector-strong Adds the canary for a wider set of functions, since it's not just those with strings that have ultimately been vulnerable to stack-busting. With this superset, more functions end up with a canary, but it still remains small compared to all functions with no measurable change in performance. Based on the original design document, a function gets the canary when it contains any of: - local variable's address used as part of the RHS of an assignment or function argument - local variable is an array (or union containing an array), regardless of array type or length - uses register local variables https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU Comparison of "size" output when built with gcc-4.9 in three configurations: - defconfig - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) text data bss dec hex filename 11430641 1457584 1191936 14080161 d6d8a1 vmlinux 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong With -strong, ARM's compressed boot code now triggers stack protection, so a static guard was added. Since this is only used during decompression and was never used before, the exposure here is very small. Once it switches to the full kernel, the stack guard is back to normal. Chrome OS has been using -fstack-protector-strong for its kernel builds for the last 8 months with no problems. Signed-off-by: Kees Cook <keescook@chromium.org> --- v3: - split off type of stack protection as a distinct config v2: - added description of all stack protector options - added size comparisons for Ubuntu and defconfig --- Makefile | 8 ++++++- arch/Kconfig | 44 +++++++++++++++++++++++++++++++++++++-- arch/arm/boot/compressed/misc.c | 14 +++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 27ed3ff7cf4c..9701b690e1ec 100644 --- a/Makefile +++ b/Makefile @@ -596,12 +596,18 @@ KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif # Handle stack protector mode. -ifdef CONFIG_CC_STACKPROTECTOR +ifdef CONFIG_CC_STACKPROTECTOR_REGULAR stackp-flag := $(call cc-option, -fstack-protector) ifeq ($(stackp-flag),) $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ -fstack-protector not supported by compiler)) endif +else ifdef CONFIG_CC_STACKPROTECTOR_STRONG + stackp-flag := $(call cc-option, -fstack-protector-strong) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ + -fstack-protector-strong not supported by compiler) + endif else # Force off for distro compilers that enable stack protector by default. stackp-flag := $(call cc-option, -fno-stack-protector) diff --git a/arch/Kconfig b/arch/Kconfig index 24e026d83072..8dde0a5b76fd 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -344,10 +344,17 @@ config HAVE_CC_STACKPROTECTOR - it has implemented a stack canary (e.g. __stack_chk_guard) config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" + def_bool n + help + Set when a stack-protector mode is enabled, so that the build + can enable kernel-side support for the GCC feature. + +choice + prompt "Stack Protector buffer overflow detection" depends on HAVE_CC_STACKPROTECTOR + default CC_STACKPROTECTOR_NONE help - This option turns on the -fstack-protector GCC feature. This + This option turns on the "stack-protector" GCC feature. This feature puts, at the beginning of functions, a canary value on the stack just before the return address, and validates the value just before actually returning. Stack based buffer @@ -355,9 +362,42 @@ config CC_STACKPROTECTOR overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. +config CC_STACKPROTECTOR_NONE + bool "None" + help + Disable "stack-protector" GCC feature. + +config CC_STACKPROTECTOR_REGULAR + bool "Regular" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added if they + have an 8-byte or larger character array on the stack. + This feature requires gcc version 4.2 or above, or a distribution gcc with the feature backported. + On an x86 "defconfig" build, this increases the kernel text by 0.3%. + +config CC_STACKPROTECTOR_STRONG + bool "Strong" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added in any + of the following conditions: + - local variable's address used as part of the RHS of an + assignment or function argument + - local variable is an array (or union containing an array), + regardless of array type or length + - uses register local variables + + This feature requires gcc version 4.9 or above, or a distribution + gcc with the feature backported. + + On an x86 "defconfig" build, this increases the kernel text by 2%. + +endchoice + config HAVE_CONTEXT_TRACKING bool help 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) error("Attempting division by 0!"); } +unsigned long __stack_chk_guard; + +void __stack_chk_guard_setup(void) +{ + __stack_chk_guard = 0x000a0dff; +} + +void __stack_chk_fail(void) +{ + error("stack-protector: Kernel stack is corrupted\n"); +} + extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); @@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, { 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; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 2/2] provide -fstack-protector-strong build option @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel This changes the stack protector config option into a choice of "None", "Regular", and "Strong". For "Strong", the kernel is built with -fstack-protector-strong (gcc 4.9 and later). This options increases the coverage of the stack protector without the heavy performance hit of -fstack-protector-all. For reference, the stack protector options available in gcc are: -fstack-protector-all: Adds the stack-canary saving prefix and stack-canary checking suffix to _all_ function entry and exit. Results in substantial use of stack space for saving the canary for deep stack users (e.g. historically xfs), and measurable (though shockingly still low) performance hit due to all the saving/checking. Really not suitable for sane systems, and was entirely removed as an option from the kernel many years ago. -fstack-protector: Adds the canary save/check to functions that define an 8 (--param=ssp-buffer-size=N, N=8 by default) or more byte local char array. Traditionally, stack overflows happened with string-based manipulations, so this was a way to find those functions. Very few total functions actually get the canary; no measurable performance or size overhead. -fstack-protector-strong Adds the canary for a wider set of functions, since it's not just those with strings that have ultimately been vulnerable to stack-busting. With this superset, more functions end up with a canary, but it still remains small compared to all functions with no measurable change in performance. Based on the original design document, a function gets the canary when it contains any of: - local variable's address used as part of the RHS of an assignment or function argument - local variable is an array (or union containing an array), regardless of array type or length - uses register local variables https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU Comparison of "size" output when built with gcc-4.9 in three configurations: - defconfig - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) text data bss dec hex filename 11430641 1457584 1191936 14080161 d6d8a1 vmlinux 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong With -strong, ARM's compressed boot code now triggers stack protection, so a static guard was added. Since this is only used during decompression and was never used before, the exposure here is very small. Once it switches to the full kernel, the stack guard is back to normal. Chrome OS has been using -fstack-protector-strong for its kernel builds for the last 8 months with no problems. Signed-off-by: Kees Cook <keescook@chromium.org> --- v3: - split off type of stack protection as a distinct config v2: - added description of all stack protector options - added size comparisons for Ubuntu and defconfig --- Makefile | 8 ++++++- arch/Kconfig | 44 +++++++++++++++++++++++++++++++++++++-- arch/arm/boot/compressed/misc.c | 14 +++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 27ed3ff7cf4c..9701b690e1ec 100644 --- a/Makefile +++ b/Makefile @@ -596,12 +596,18 @@ KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif # Handle stack protector mode. -ifdef CONFIG_CC_STACKPROTECTOR +ifdef CONFIG_CC_STACKPROTECTOR_REGULAR stackp-flag := $(call cc-option, -fstack-protector) ifeq ($(stackp-flag),) $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ -fstack-protector not supported by compiler)) endif +else ifdef CONFIG_CC_STACKPROTECTOR_STRONG + stackp-flag := $(call cc-option, -fstack-protector-strong) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ + -fstack-protector-strong not supported by compiler) + endif else # Force off for distro compilers that enable stack protector by default. stackp-flag := $(call cc-option, -fno-stack-protector) diff --git a/arch/Kconfig b/arch/Kconfig index 24e026d83072..8dde0a5b76fd 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -344,10 +344,17 @@ config HAVE_CC_STACKPROTECTOR - it has implemented a stack canary (e.g. __stack_chk_guard) config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" + def_bool n + help + Set when a stack-protector mode is enabled, so that the build + can enable kernel-side support for the GCC feature. + +choice + prompt "Stack Protector buffer overflow detection" depends on HAVE_CC_STACKPROTECTOR + default CC_STACKPROTECTOR_NONE help - This option turns on the -fstack-protector GCC feature. This + This option turns on the "stack-protector" GCC feature. This feature puts, at the beginning of functions, a canary value on the stack just before the return address, and validates the value just before actually returning. Stack based buffer @@ -355,9 +362,42 @@ config CC_STACKPROTECTOR overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. +config CC_STACKPROTECTOR_NONE + bool "None" + help + Disable "stack-protector" GCC feature. + +config CC_STACKPROTECTOR_REGULAR + bool "Regular" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added if they + have an 8-byte or larger character array on the stack. + This feature requires gcc version 4.2 or above, or a distribution gcc with the feature backported. + On an x86 "defconfig" build, this increases the kernel text by 0.3%. + +config CC_STACKPROTECTOR_STRONG + bool "Strong" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added in any + of the following conditions: + - local variable's address used as part of the RHS of an + assignment or function argument + - local variable is an array (or union containing an array), + regardless of array type or length + - uses register local variables + + This feature requires gcc version 4.9 or above, or a distribution + gcc with the feature backported. + + On an x86 "defconfig" build, this increases the kernel text by 2%. + +endchoice + config HAVE_CONTEXT_TRACKING bool help 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) error("Attempting division by 0!"); } +unsigned long __stack_chk_guard; + +void __stack_chk_guard_setup(void) +{ + __stack_chk_guard = 0x000a0dff; +} + +void __stack_chk_fail(void) +{ + error("stack-protector: Kernel stack is corrupted\n"); +} + extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); @@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, { 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; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 2/2] provide -fstack-protector-strong build option @ 2013-12-17 22:43 ` Kees Cook 0 siblings, 0 replies; 12+ messages in thread From: Kees Cook @ 2013-12-17 22:43 UTC (permalink / raw) To: linux-arm-kernel This changes the stack protector config option into a choice of "None", "Regular", and "Strong". For "Strong", the kernel is built with -fstack-protector-strong (gcc 4.9 and later). This options increases the coverage of the stack protector without the heavy performance hit of -fstack-protector-all. For reference, the stack protector options available in gcc are: -fstack-protector-all: Adds the stack-canary saving prefix and stack-canary checking suffix to _all_ function entry and exit. Results in substantial use of stack space for saving the canary for deep stack users (e.g. historically xfs), and measurable (though shockingly still low) performance hit due to all the saving/checking. Really not suitable for sane systems, and was entirely removed as an option from the kernel many years ago. -fstack-protector: Adds the canary save/check to functions that define an 8 (--param=ssp-buffer-size=N, N=8 by default) or more byte local char array. Traditionally, stack overflows happened with string-based manipulations, so this was a way to find those functions. Very few total functions actually get the canary; no measurable performance or size overhead. -fstack-protector-strong Adds the canary for a wider set of functions, since it's not just those with strings that have ultimately been vulnerable to stack-busting. With this superset, more functions end up with a canary, but it still remains small compared to all functions with no measurable change in performance. Based on the original design document, a function gets the canary when it contains any of: - local variable's address used as part of the RHS of an assignment or function argument - local variable is an array (or union containing an array), regardless of array type or length - uses register local variables https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU Comparison of "size" output when built with gcc-4.9 in three configurations: - defconfig - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) text data bss dec hex filename 11430641 1457584 1191936 14080161 d6d8a1 vmlinux 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong With -strong, ARM's compressed boot code now triggers stack protection, so a static guard was added. Since this is only used during decompression and was never used before, the exposure here is very small. Once it switches to the full kernel, the stack guard is back to normal. Chrome OS has been using -fstack-protector-strong for its kernel builds for the last 8 months with no problems. Signed-off-by: Kees Cook <keescook@chromium.org> --- v3: - split off type of stack protection as a distinct config v2: - added description of all stack protector options - added size comparisons for Ubuntu and defconfig --- Makefile | 8 ++++++- arch/Kconfig | 44 +++++++++++++++++++++++++++++++++++++-- arch/arm/boot/compressed/misc.c | 14 +++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 27ed3ff7cf4c..9701b690e1ec 100644 --- a/Makefile +++ b/Makefile @@ -596,12 +596,18 @@ KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif # Handle stack protector mode. -ifdef CONFIG_CC_STACKPROTECTOR +ifdef CONFIG_CC_STACKPROTECTOR_REGULAR stackp-flag := $(call cc-option, -fstack-protector) ifeq ($(stackp-flag),) $(error Cannot use CONFIG_CC_STACKPROTECTOR: \ -fstack-protector not supported by compiler)) endif +else ifdef CONFIG_CC_STACKPROTECTOR_STRONG + stackp-flag := $(call cc-option, -fstack-protector-strong) + ifeq ($(stackp-flag),) + $(error Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ + -fstack-protector-strong not supported by compiler) + endif else # Force off for distro compilers that enable stack protector by default. stackp-flag := $(call cc-option, -fno-stack-protector) diff --git a/arch/Kconfig b/arch/Kconfig index 24e026d83072..8dde0a5b76fd 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -344,10 +344,17 @@ config HAVE_CC_STACKPROTECTOR - it has implemented a stack canary (e.g. __stack_chk_guard) config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" + def_bool n + help + Set when a stack-protector mode is enabled, so that the build + can enable kernel-side support for the GCC feature. + +choice + prompt "Stack Protector buffer overflow detection" depends on HAVE_CC_STACKPROTECTOR + default CC_STACKPROTECTOR_NONE help - This option turns on the -fstack-protector GCC feature. This + This option turns on the "stack-protector" GCC feature. This feature puts, at the beginning of functions, a canary value on the stack just before the return address, and validates the value just before actually returning. Stack based buffer @@ -355,9 +362,42 @@ config CC_STACKPROTECTOR overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. +config CC_STACKPROTECTOR_NONE + bool "None" + help + Disable "stack-protector" GCC feature. + +config CC_STACKPROTECTOR_REGULAR + bool "Regular" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added if they + have an 8-byte or larger character array on the stack. + This feature requires gcc version 4.2 or above, or a distribution gcc with the feature backported. + On an x86 "defconfig" build, this increases the kernel text by 0.3%. + +config CC_STACKPROTECTOR_STRONG + bool "Strong" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added in any + of the following conditions: + - local variable's address used as part of the RHS of an + assignment or function argument + - local variable is an array (or union containing an array), + regardless of array type or length + - uses register local variables + + This feature requires gcc version 4.9 or above, or a distribution + gcc with the feature backported. + + On an x86 "defconfig" build, this increases the kernel text by 2%. + +endchoice + config HAVE_CONTEXT_TRACKING bool help 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) error("Attempting division by 0!"); } +unsigned long __stack_chk_guard; + +void __stack_chk_guard_setup(void) +{ + __stack_chk_guard = 0x000a0dff; +} + +void __stack_chk_fail(void) +{ + error("stack-protector: Kernel stack is corrupted\n"); +} + extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); @@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, { 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; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/2] provide -fstack-protector-strong build option 2013-12-17 22:43 ` Kees Cook (?) @ 2013-12-18 9:59 ` Ingo Molnar -1 siblings, 0 replies; 12+ messages in thread From: Ingo Molnar @ 2013-12-18 9:59 UTC (permalink / raw) To: Kees Cook Cc: linux-kernel, Michal Marek, Russell King, Ralf Baechle, Paul Mundt, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton, James Hogan, Stephen Rothwell, Shawn Guo, x86, linux-kbuild, linux-arm-kernel, linux-mips, linux-sh * Kees Cook <keescook@chromium.org> wrote: > This changes the stack protector config option into a choice of "None", > "Regular", and "Strong". For "Strong", the kernel is built with > -fstack-protector-strong (gcc 4.9 and later). This options increases > the coverage of the stack protector without the heavy performance hit > of -fstack-protector-all. > > For reference, the stack protector options available in gcc are: > > -fstack-protector-all: > Adds the stack-canary saving prefix and stack-canary checking suffix to > _all_ function entry and exit. Results in substantial use of stack space > for saving the canary for deep stack users (e.g. historically xfs), and > measurable (though shockingly still low) performance hit due to all the > saving/checking. Really not suitable for sane systems, and was entirely > removed as an option from the kernel many years ago. > > -fstack-protector: > Adds the canary save/check to functions that define an 8 > (--param=ssp-buffer-size=N, N=8 by default) or more byte local char > array. Traditionally, stack overflows happened with string-based > manipulations, so this was a way to find those functions. Very few > total functions actually get the canary; no measurable performance or > size overhead. > > -fstack-protector-strong > Adds the canary for a wider set of functions, since it's not just those > with strings that have ultimately been vulnerable to stack-busting. With > this superset, more functions end up with a canary, but it still > remains small compared to all functions with no measurable change in > performance. Based on the original design document, a function gets the > canary when it contains any of: > - local variable's address used as part of the RHS of an assignment or > function argument > - local variable is an array (or union containing an array), regardless > of array type or length > - uses register local variables > https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU > > Comparison of "size" output when built with gcc-4.9 in three configurations: > - defconfig > - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) > - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) > > text data bss dec hex filename > 11430641 1457584 1191936 14080161 d6d8a1 vmlinux > 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector > 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong Beyond the kernel size calculation, could you please also provide an estimation about the _number_ of functions affected, out of N kernel functions, so that the user has a rough picture about the scope and distribution of these variants? I.e. something like: # of canary checks .................................................................................. - defconfig 0 functions out of 100k functions - defconfig + STACKPROTECTOR 1k functions out of 100k functions - defconfig + STACKPROTECTOR_STRONG 20k functions out of 100k functions Thanks, Ingo ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/2] provide -fstack-protector-strong build option @ 2013-12-18 9:59 ` Ingo Molnar 0 siblings, 0 replies; 12+ messages in thread From: Ingo Molnar @ 2013-12-18 9:59 UTC (permalink / raw) To: linux-arm-kernel * Kees Cook <keescook@chromium.org> wrote: > This changes the stack protector config option into a choice of "None", > "Regular", and "Strong". For "Strong", the kernel is built with > -fstack-protector-strong (gcc 4.9 and later). This options increases > the coverage of the stack protector without the heavy performance hit > of -fstack-protector-all. > > For reference, the stack protector options available in gcc are: > > -fstack-protector-all: > Adds the stack-canary saving prefix and stack-canary checking suffix to > _all_ function entry and exit. Results in substantial use of stack space > for saving the canary for deep stack users (e.g. historically xfs), and > measurable (though shockingly still low) performance hit due to all the > saving/checking. Really not suitable for sane systems, and was entirely > removed as an option from the kernel many years ago. > > -fstack-protector: > Adds the canary save/check to functions that define an 8 > (--param=ssp-buffer-size=N, N=8 by default) or more byte local char > array. Traditionally, stack overflows happened with string-based > manipulations, so this was a way to find those functions. Very few > total functions actually get the canary; no measurable performance or > size overhead. > > -fstack-protector-strong > Adds the canary for a wider set of functions, since it's not just those > with strings that have ultimately been vulnerable to stack-busting. With > this superset, more functions end up with a canary, but it still > remains small compared to all functions with no measurable change in > performance. Based on the original design document, a function gets the > canary when it contains any of: > - local variable's address used as part of the RHS of an assignment or > function argument > - local variable is an array (or union containing an array), regardless > of array type or length > - uses register local variables > https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU > > Comparison of "size" output when built with gcc-4.9 in three configurations: > - defconfig > - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) > - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) > > text data bss dec hex filename > 11430641 1457584 1191936 14080161 d6d8a1 vmlinux > 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector > 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong Beyond the kernel size calculation, could you please also provide an estimation about the _number_ of functions affected, out of N kernel functions, so that the user has a rough picture about the scope and distribution of these variants? I.e. something like: # of canary checks .................................................................................. - defconfig 0 functions out of 100k functions - defconfig + STACKPROTECTOR 1k functions out of 100k functions - defconfig + STACKPROTECTOR_STRONG 20k functions out of 100k functions Thanks, Ingo ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/2] provide -fstack-protector-strong build option @ 2013-12-18 9:59 ` Ingo Molnar 0 siblings, 0 replies; 12+ messages in thread From: Ingo Molnar @ 2013-12-18 9:59 UTC (permalink / raw) To: linux-arm-kernel * Kees Cook <keescook@chromium.org> wrote: > This changes the stack protector config option into a choice of "None", > "Regular", and "Strong". For "Strong", the kernel is built with > -fstack-protector-strong (gcc 4.9 and later). This options increases > the coverage of the stack protector without the heavy performance hit > of -fstack-protector-all. > > For reference, the stack protector options available in gcc are: > > -fstack-protector-all: > Adds the stack-canary saving prefix and stack-canary checking suffix to > _all_ function entry and exit. Results in substantial use of stack space > for saving the canary for deep stack users (e.g. historically xfs), and > measurable (though shockingly still low) performance hit due to all the > saving/checking. Really not suitable for sane systems, and was entirely > removed as an option from the kernel many years ago. > > -fstack-protector: > Adds the canary save/check to functions that define an 8 > (--param=ssp-buffer-size=N, N=8 by default) or more byte local char > array. Traditionally, stack overflows happened with string-based > manipulations, so this was a way to find those functions. Very few > total functions actually get the canary; no measurable performance or > size overhead. > > -fstack-protector-strong > Adds the canary for a wider set of functions, since it's not just those > with strings that have ultimately been vulnerable to stack-busting. With > this superset, more functions end up with a canary, but it still > remains small compared to all functions with no measurable change in > performance. Based on the original design document, a function gets the > canary when it contains any of: > - local variable's address used as part of the RHS of an assignment or > function argument > - local variable is an array (or union containing an array), regardless > of array type or length > - uses register local variables > https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU > > Comparison of "size" output when built with gcc-4.9 in three configurations: > - defconfig > - defconfig + CONFIG_CC_STACKPROTECTOR (+0.33%) > - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch (+2.24%) > > text data bss dec hex filename > 11430641 1457584 1191936 14080161 d6d8a1 vmlinux > 11468490 1457584 1191936 14118010 d76c7a vmlinux.stackprotector > 11692790 1457584 1191936 14342310 dad8a6 vmlinux.stackprotector-strong Beyond the kernel size calculation, could you please also provide an estimation about the _number_ of functions affected, out of N kernel functions, so that the user has a rough picture about the scope and distribution of these variants? I.e. something like: # of canary checks .................................................................................. - defconfig 0 functions out of 100k functions - defconfig + STACKPROTECTOR 1k functions out of 100k functions - defconfig + STACKPROTECTOR_STRONG 20k functions out of 100k functions Thanks, Ingo ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-12-18 9:59 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-12-17 22:43 [PATCH v3] provide -fstack-protector-strong build option Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-17 22:43 ` [PATCH v3 1/2] create HAVE_CC_STACKPROTECTOR for centralized use Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-17 22:43 ` [PATCH v3 2/2] provide -fstack-protector-strong build option Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-17 22:43 ` Kees Cook 2013-12-18 9:59 ` Ingo Molnar 2013-12-18 9:59 ` Ingo Molnar 2013-12-18 9:59 ` Ingo Molnar
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.