History

Makefile: introduce CONFIG_CC_STACKPROTECTOR_AUTO

Nearly all modern compilers support a stack-protector option, and nearly all modern distributions enable the kernel stack-protector, so enabling this by default in kernel builds would make sense. However, Kconfig does not have knowledge of available compiler features, so it isn't safe to force on, as this would unconditionally break builds for the compilers or architectures that don't have support. Instead, this introduces a new option, CONFIG_CC_STACKPROTECTOR_AUTO, which attempts to discover the best possible stack-protector available, and will allow builds to proceed even if the compiler doesn't support any stack-protector. This option is made the default so that kernels built with modern compilers will be protected-by-default against stack buffer overflows, avoiding things like the recent BlueBorne attack. Selection of a specific stack-protector option remains available, including disabling it. Additionally, tiny.config is adjusted to use CC_STACKPROTECTOR_NONE, since that's the option with the least code size (and it used to be the default, so we have to explicitly choose it there now).

Kees Cook committed 8 years ago

Commit 44c6dc91 parent 2bc2f683 files · +45 −4Browse files

Unified · Split

3 files
  1. Makefile +34 −3
  2. arch/Kconfig +7 −1
  3. kernel/configs/tiny.config +4 −0
Makefile+34−3
@@ -680,6 +680,10 @@ endif · 679 unmodified lines
680680 # This selects the stack protector compiler flag. Testing it is delayed
681681 # until after .config has been reprocessed, in the prepare-compiler-check
682682 # target.
683+ifdef CONFIG_CC_STACKPROTECTOR_AUTO
684+ stackp-flag := $(call cc-option,-fstack-protector-strong,$(call cc-option,-fstack-protector))
685+ stackp-name := AUTO
686+else
683687 ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
684688 stackp-flag := -fstack-protector
685689 stackp-name := REGULAR
@@ -688,12 +692,18 @@ ifdef CONFIG_CC_STACKPROTECTOR_STRONG · 2 unmodified lines
688692 stackp-flag := -fstack-protector-strong
689693 stackp-name := STRONG
690694 else
695+ # If either there is no stack protector for this architecture or
696+ # CONFIG_CC_STACKPROTECTOR_NONE is selected, we're done, and $(stackp-name)
697+ # is empty, skipping all remaining stack protector tests.
698+ #
691699 # Force off for distro compilers that enable stack protector by default.
692− stackp-flag := $(call cc-option, -fno-stack-protector)
700+ KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
701+endif
693702 endif
694703 endif
695704 # Find arch-specific stack protector compiler sanity-checking script.
696705 ifdef stackp-name
706+ifneq ($(stackp-flag),)
697707 stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh
698708 stackp-check := $(wildcard $(stackp-path))
699709 # If the wildcard test matches a test script, run it to check functionality.
@@ -705,9 +715,17 @@ ifdef stackp-name · 5 unmodified lines
705715 ifndef stackp-broken
706716 # If the stack protector is functional, enable code that depends on it.
707717 KBUILD_CPPFLAGS += -DCONFIG_CC_STACKPROTECTOR
718+ # Either we've already detected the flag (for AUTO) or we'll fail the
719+ # build in the prepare-compiler-check rule (for specific flag).
720+ KBUILD_CFLAGS += $(stackp-flag)
721+ else
722+ # We have to make sure stack protector is unconditionally disabled if
723+ # the compiler is broken (in case we're going to continue the build in
724+ # AUTO mode).
725+ KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
708726 endif
709727 endif
710−KBUILD_CFLAGS += $(stackp-flag)
728+endif
711729
712730 ifeq ($(cc-name),clang)
713731 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
@@ -1102,15 +1120,28 @@ PHONY += prepare-compiler-check · 388 unmodified lines
11021120 prepare-compiler-check: FORCE
11031121 # Make sure compiler supports requested stack protector flag.
11041122 ifdef stackp-name
1123+ # Warn about CONFIG_CC_STACKPROTECTOR_AUTO having found no option.
1124+ ifeq ($(stackp-flag),)
1125+ @echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
1126+ Compiler does not support any known stack-protector >&2
1127+ else
1128+ # Fail if specifically requested stack protector is missing.
11051129 ifeq ($(call cc-option, $(stackp-flag)),)
11061130 @echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
11071131 $(stackp-flag) not supported by compiler >&2 && exit 1
11081132 endif
1133+ endif
11091134 endif
1110−# Make sure compiler does not have buggy stack-protector support.
1135+# Make sure compiler does not have buggy stack-protector support. If a
1136+# specific stack-protector was requested, fail the build, otherwise warn.
11111137 ifdef stackp-broken
1138+ ifeq ($(stackp-name),AUTO)
1139+ @echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
1140+ $(stackp-flag) available but compiler is broken: disabling >&2
1141+ else
11121142 @echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
11131143 $(stackp-flag) available but compiler is broken >&2 && exit 1
1144+ endif
11141145 endif
11151146 @:
11161147
arch/Kconfig+7−1
@@ -541,7 +541,7 @@ config HAVE_CC_STACKPROTECTOR · 540 unmodified lines
541541 choice
542542 prompt "Stack Protector buffer overflow detection"
543543 depends on HAVE_CC_STACKPROTECTOR
544− default CC_STACKPROTECTOR_NONE
544+ default CC_STACKPROTECTOR_AUTO
545545 help
546546 This option turns on the "stack-protector" GCC feature. This
547547 feature puts, at the beginning of functions, a canary value on
@@ -588,6 +588,12 @@ config CC_STACKPROTECTOR_STRONG · 40 unmodified lines
588588 about 20% of all kernel functions, which increases the kernel code
589589 size by about 2%.
590590
591+config CC_STACKPROTECTOR_AUTO
592+ bool "Automatic"
593+ help
594+ If the compiler supports it, the best available stack-protector
595+ option will be chosen.
596+
591597 endchoice
592598
593599 config THIN_ARCHIVES
kernel/configs/tiny.config+4−0
@@ -10,3 +10,7 @@ CONFIG_OPTIMIZE_INLINING=y · 9 unmodified lines
1010 # CONFIG_SLAB is not set
1111 # CONFIG_SLUB is not set
1212 CONFIG_SLOB=y
13+CONFIG_CC_STACKPROTECTOR_NONE=y
14+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
15+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
16+# CONFIG_CC_STACKPROTECTOR_AUTO is not set