linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO
@ 2017-11-07 17:38 Kees Cook
  2017-11-07 17:38 ` [PATCH v2 1/3] Makefile: Move stack-protector compiler breakage test earlier Kees Cook
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Kees Cook @ 2017-11-07 17:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Masahiro Yamada, Arnd Bergmann, Josh Triplett,
	Nicholas Piggin, Laura Abbott, linux-kbuild, linux-kernel

As described in the final patch:

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.


This has lived over the last several days without any unfixed 0day failures.

v2:
- under ..._AUTO, warn and continue on _all_ stack protector failure cases
- fix 32-bit boot regression due to lazy gz.
- set CONFIG_CC_STACKPROTECTOR_NONE for tiny.config.

Thanks,

-Kees

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/3] Makefile: Move stack-protector compiler breakage test earlier
  2017-11-07 17:38 [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
@ 2017-11-07 17:38 ` Kees Cook
  2017-11-07 17:38 ` [PATCH v2 2/3] Makefile: Move stack-protector availability out of Kconfig Kees Cook
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2017-11-07 17:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Masahiro Yamada, Arnd Bergmann, linux-kbuild,
	Josh Triplett, Nicholas Piggin, Laura Abbott, linux-kernel

In order to make stack-protector failures warn instead of unconditionally
breaking the build, this moves the compiler output sanity-check earlier,
and sets a flag for later testing. Future patches can choose to warn or
fail, depending on the flag value.

Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-kbuild@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Makefile | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index cf007a31d575..caa3f7e6f524 100644
--- a/Makefile
+++ b/Makefile
@@ -692,6 +692,12 @@ endif
 ifdef CONFIG_CC_STACKPROTECTOR
   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.
+  ifdef stackp-check
+    ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+      stackp-broken := y
+    endif
+  endif
 endif
 KBUILD_CFLAGS += $(stackp-flag)
 
@@ -1087,11 +1093,9 @@ ifdef stackp-name
   endif
 endif
 # Make sure compiler does not have buggy stack-protector support.
-ifdef stackp-check
-  ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+ifdef stackp-broken
 	@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
                   $(stackp-flag) available but compiler is broken >&2 && exit 1
-  endif
 endif
 	@:
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/3] Makefile: Move stack-protector availability out of Kconfig
  2017-11-07 17:38 [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
  2017-11-07 17:38 ` [PATCH v2 1/3] Makefile: Move stack-protector compiler breakage test earlier Kees Cook
@ 2017-11-07 17:38 ` Kees Cook
  2017-11-07 17:38 ` [PATCH v2 3/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
  2017-11-08 19:43 ` [PATCH v2 0/3] " Laura Abbott
  3 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2017-11-07 17:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Masahiro Yamada, Arnd Bergmann, linux-kbuild,
	Josh Triplett, Nicholas Piggin, Laura Abbott, linux-kernel

Various portions of the kernel, especially per-architecture pieces,
need to know if the compiler is building with the stack protector.
This was done in the arch/Kconfig with 'select', but this doesn't
allow a way to do auto-detected compiler support. In preparation for
creating an on-if-available default, move the logic for the definition of
CONFIG_CC_STACKPROTECTOR into the Makefile.

Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-kbuild@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Makefile         | 6 +++++-
 arch/Kconfig     | 8 --------
 arch/x86/Kconfig | 2 +-
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index caa3f7e6f524..b486c0271866 100644
--- a/Makefile
+++ b/Makefile
@@ -689,7 +689,7 @@ else
 endif
 endif
 # Find arch-specific stack protector compiler sanity-checking script.
-ifdef CONFIG_CC_STACKPROTECTOR
+ifdef stackp-name
   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.
@@ -698,6 +698,10 @@ ifdef CONFIG_CC_STACKPROTECTOR
       stackp-broken := y
     endif
   endif
+  ifndef stackp-broken
+    # If the stack protector is functional, enable code that depends on it.
+    KBUILD_CPPFLAGS += -DCONFIG_CC_STACKPROTECTOR
+  endif
 endif
 KBUILD_CFLAGS += $(stackp-flag)
 
diff --git a/arch/Kconfig b/arch/Kconfig
index 1aafb4efbb51..7007c1bfa79c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -523,12 +523,6 @@ config HAVE_CC_STACKPROTECTOR
 	  - its compiler supports the -fstack-protector option
 	  - it has implemented a stack canary (e.g. __stack_chk_guard)
 
-config CC_STACKPROTECTOR
-	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
@@ -549,7 +543,6 @@ config CC_STACKPROTECTOR_NONE
 
 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.
@@ -563,7 +556,6 @@ config CC_STACKPROTECTOR_REGULAR
 
 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:
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 971feac13506..8d3847071707 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -319,7 +319,7 @@ config X86_64_SMP
 
 config X86_32_LAZY_GS
 	def_bool y
-	depends on X86_32 && !CC_STACKPROTECTOR
+	depends on X86_32 && CC_STACKPROTECTOR_NONE
 
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO
  2017-11-07 17:38 [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
  2017-11-07 17:38 ` [PATCH v2 1/3] Makefile: Move stack-protector compiler breakage test earlier Kees Cook
  2017-11-07 17:38 ` [PATCH v2 2/3] Makefile: Move stack-protector availability out of Kconfig Kees Cook
@ 2017-11-07 17:38 ` Kees Cook
  2017-11-08 19:43 ` [PATCH v2 0/3] " Laura Abbott
  3 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2017-11-07 17:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Masahiro Yamada, Arnd Bergmann, Josh Triplett,
	linux-kbuild, Nicholas Piggin, Laura Abbott, linux-kernel

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).

Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: linux-kbuild@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Makefile                   | 37 ++++++++++++++++++++++++++++++++++---
 arch/Kconfig               |  8 +++++++-
 kernel/configs/tiny.config |  4 ++++
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index b486c0271866..a1e8dd1ab236 100644
--- a/Makefile
+++ b/Makefile
@@ -676,6 +676,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
@@ -684,12 +688,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.
@@ -701,9 +711,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)
 ifneq ($(CROSS_COMPILE),)
@@ -1091,15 +1109,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 7007c1bfa79c..cd2676ff5d5d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -526,7 +526,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
@@ -573,6 +573,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
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO
  2017-11-07 17:38 [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
                   ` (2 preceding siblings ...)
  2017-11-07 17:38 ` [PATCH v2 3/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
@ 2017-11-08 19:43 ` Laura Abbott
  2017-11-09  1:12   ` Kees Cook
  3 siblings, 1 reply; 6+ messages in thread
From: Laura Abbott @ 2017-11-08 19:43 UTC (permalink / raw)
  To: Kees Cook, Andrew Morton
  Cc: Masahiro Yamada, Arnd Bergmann, Josh Triplett, Nicholas Piggin,
	linux-kbuild, linux-kernel

On 11/07/2017 09:38 AM, Kees Cook wrote:
> As described in the final patch:
> 
> 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.
> 
> 
> This has lived over the last several days without any unfixed 0day failures.
> 
> v2:
> - under ..._AUTO, warn and continue on _all_ stack protector failure cases
> - fix 32-bit boot regression due to lazy gz.
> - set CONFIG_CC_STACKPROTECTOR_NONE for tiny.config.
> 
> Thanks,
> 
> -Kees
> 

This passed a test build on all Fedora arches, including s390 and ppc.
On x86 it picks up the strong option correctly.

You're welcome to add

Tested-by: Laura Abbott <labbott@redhat.com>

Thanks,
Laura

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO
  2017-11-08 19:43 ` [PATCH v2 0/3] " Laura Abbott
@ 2017-11-09  1:12   ` Kees Cook
  0 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2017-11-09  1:12 UTC (permalink / raw)
  To: Laura Abbott
  Cc: Andrew Morton, Masahiro Yamada, Arnd Bergmann, Josh Triplett,
	Nicholas Piggin, linux-kbuild, LKML

On Wed, Nov 8, 2017 at 11:43 AM, Laura Abbott <labbott@redhat.com> wrote:
> On 11/07/2017 09:38 AM, Kees Cook wrote:
>>
>> As described in the final patch:
>>
>> 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.
>>
>>
>> This has lived over the last several days without any unfixed 0day
>> failures.
>>
>> v2:
>> - under ..._AUTO, warn and continue on _all_ stack protector failure cases
>> - fix 32-bit boot regression due to lazy gz.
>> - set CONFIG_CC_STACKPROTECTOR_NONE for tiny.config.
>>
>> Thanks,
>>
>> -Kees
>>
>
> This passed a test build on all Fedora arches, including s390 and ppc.
> On x86 it picks up the strong option correctly.
>
> You're welcome to add
>
> Tested-by: Laura Abbott <labbott@redhat.com>

Awesome, thanks for testing!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-11-09  1:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-07 17:38 [PATCH v2 0/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
2017-11-07 17:38 ` [PATCH v2 1/3] Makefile: Move stack-protector compiler breakage test earlier Kees Cook
2017-11-07 17:38 ` [PATCH v2 2/3] Makefile: Move stack-protector availability out of Kconfig Kees Cook
2017-11-07 17:38 ` [PATCH v2 3/3] Makefile: Introduce CONFIG_CC_STACKPROTECTOR_AUTO Kees Cook
2017-11-08 19:43 ` [PATCH v2 0/3] " Laura Abbott
2017-11-09  1:12   ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).