Makefile: introduce CONFIG_CC_STACKPROTECTOR_AUTO

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/44c6dc940b190cf22b044a784f3e00a7e7f08b2f
Commit:     44c6dc940b190cf22b044a784f3e00a7e7f08b2f
Parent:     2bc2f688fdf8808de4f36be563ccdb0bde7c0c54
Refname:    refs/heads/master
Author:     Kees Cook <[email protected]>
AuthorDate: Tue Feb 6 15:37:45 2018 -0800
Committer:  Linus Torvalds <[email protected]>
CommitDate: Tue Feb 6 18:32:44 2018 -0800

    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).
    
    Link: http://lkml.kernel.org/r/[email protected]
    Signed-off-by: Kees Cook <[email protected]>
    Tested-by: Laura Abbott <[email protected]>
    Cc: Masahiro Yamada <[email protected]>
    Cc: Arnd Bergmann <[email protected]>
    Cc: Josh Triplett <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Signed-off-by: Linus Torvalds <[email protected]>
---
 Makefile                   | 37 ++++++++++++++++++++++++++++++++++---
 arch/Kconfig               |  8 +++++++-
 kernel/configs/tiny.config |  4 ++++
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index f0f934097f64..d192dd826cce 100644
--- a/Makefile
+++ b/Makefile
@@ -680,6 +680,10 @@ endif
 # This selects the stack protector compiler flag. Testing it is delayed
 # until after .config has been reprocessed, in the prepare-compiler-check
 # target.
+ifdef CONFIG_CC_STACKPROTECTOR_AUTO
+  stackp-flag := $(call cc-option,-fstack-protector-strong,$(call cc-option,-fstack-protector))
+  stackp-name := AUTO
+else
 ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
   stackp-flag := -fstack-protector
   stackp-name := REGULAR
@@ -688,12 +692,18 @@ ifdef CONFIG_CC_STACKPROTECTOR_STRONG
   stackp-flag := -fstack-protector-strong
   stackp-name := STRONG
 else
+  # If either there is no stack protector for this architecture or
+  # CONFIG_CC_STACKPROTECTOR_NONE is selected, we're done, and $(stackp-name)
+  # is empty, skipping all remaining stack protector tests.
+  #
   # Force off for distro compilers that enable stack protector by default.
-  stackp-flag := $(call cc-option, -fno-stack-protector)
+  KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+endif
 endif
 endif
 # Find arch-specific stack protector compiler sanity-checking script.
 ifdef stackp-name
+ifneq ($(stackp-flag),)
   stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh
   stackp-check := $(wildcard $(stackp-path))
   # If the wildcard test matches a test script, run it to check functionality.
@@ -705,9 +715,17 @@ ifdef stackp-name
   ifndef stackp-broken
     # If the stack protector is functional, enable code that depends on it.
     KBUILD_CPPFLAGS += -DCONFIG_CC_STACKPROTECTOR
+    # Either we've already detected the flag (for AUTO) or we'll fail the
+    # build in the prepare-compiler-check rule (for specific flag).
+    KBUILD_CFLAGS += $(stackp-flag)
+  else
+    # We have to make sure stack protector is unconditionally disabled if
+    # the compiler is broken (in case we're going to continue the build in
+    # AUTO mode).
+    KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
   endif
 endif
-KBUILD_CFLAGS += $(stackp-flag)
+endif
 
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
@@ -1102,15 +1120,28 @@ PHONY += prepare-compiler-check
 prepare-compiler-check: FORCE
 # Make sure compiler supports requested stack protector flag.
 ifdef stackp-name
+  # Warn about CONFIG_CC_STACKPROTECTOR_AUTO having found no option.
+  ifeq ($(stackp-flag),)
+	@echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+		  Compiler does not support any known stack-protector >&2
+  else
+  # Fail if specifically requested stack protector is missing.
   ifeq ($(call cc-option, $(stackp-flag)),)
 	@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
 		  $(stackp-flag) not supported by compiler >&2 && exit 1
   endif
+  endif
 endif
-# Make sure compiler does not have buggy stack-protector support.
+# Make sure compiler does not have buggy stack-protector support. If a
+# specific stack-protector was requested, fail the build, otherwise warn.
 ifdef stackp-broken
+  ifeq ($(stackp-name),AUTO)
+	@echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+                  $(stackp-flag) available but compiler is broken: disabling >&2
+  else
 	@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
                   $(stackp-flag) available but compiler is broken >&2 && exit 1
+  endif
 endif
 	@:
 
diff --git a/arch/Kconfig b/arch/Kconfig
index 9330a9d79dc3..76c0b54443b1 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -541,7 +541,7 @@ config HAVE_CC_STACKPROTECTOR
 choice
 	prompt "Stack Protector buffer overflow detection"
 	depends on HAVE_CC_STACKPROTECTOR
-	default CC_STACKPROTECTOR_NONE
+	default CC_STACKPROTECTOR_AUTO
 	help
 	  This option turns on the "stack-protector" GCC feature. This
 	  feature puts, at the beginning of functions, a canary value on
@@ -588,6 +588,12 @@ config CC_STACKPROTECTOR_STRONG
 	  about 20% of all kernel functions, which increases the kernel code
 	  size by about 2%.
 
+config CC_STACKPROTECTOR_AUTO
+	bool "Automatic"
+	help
+	  If the compiler supports it, the best available stack-protector
+	  option will be chosen.
+
 endchoice
 
 config THIN_ARCHIVES
diff --git a/kernel/configs/tiny.config b/kernel/configs/tiny.config
index 7fa0c4ae6394..9bfdffc100da 100644
--- a/kernel/configs/tiny.config
+++ b/kernel/configs/tiny.config
@@ -10,3 +10,7 @@ CONFIG_OPTIMIZE_INLINING=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+CONFIG_CC_STACKPROTECTOR_NONE=y
+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+# CONFIG_CC_STACKPROTECTOR_AUTO is not set
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.