aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2016-07-26 17:26:20 -0400
committerMichal Marek <mmarek@suse.com>2016-07-26 17:50:59 -0400
commit228d96c603cf53e32f672c0e459d2adbc5a4609a (patch)
treee6d936927424b32c693ad20f61f1990094765008
parent21532b9e5bd597631cfe38d9eb34df069938065b (diff)
kbuild: Abort build on bad stack protector flag
Before, the stack protector flag was sanity checked before .config had been reprocessed. This meant the build couldn't be aborted early, and only a warning could be emitted followed later by the compiler blowing up with an unknown flag. This has caused a lot of confusion over time, so this splits the flag selection from sanity checking and performs the sanity checking after the make has been restarted from a reprocessed .config, so builds can be aborted as early as possible now. Additionally moves the x86-specific sanity check to the same location, since it suffered from the same warn-then-wait-for-compiler-failure problem. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Michal Marek <mmarek@suse.com>
-rw-r--r--Makefile67
-rw-r--r--arch/x86/Makefile8
2 files changed, 40 insertions, 35 deletions
diff --git a/Makefile b/Makefile
index 7aa6f8c4cc53..08aac0a7c85f 100644
--- a/Makefile
+++ b/Makefile
@@ -655,41 +655,26 @@ ifneq ($(CONFIG_FRAME_WARN),0)
655KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) 655KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
656endif 656endif
657 657
658# Handle stack protector mode. 658# This selects the stack protector compiler flag. Testing it is delayed
659# 659# until after .config has been reprocessed, in the prepare-compiler-check
660# Since kbuild can potentially perform two passes (first with the old 660# target.
661# .config values and then with updated .config values), we cannot error out
662# if a desired compiler option is unsupported. If we were to error, kbuild
663# could never get to the second pass and actually notice that we changed
664# the option to something that was supported.
665#
666# Additionally, we don't want to fallback and/or silently change which compiler
667# flags will be used, since that leads to producing kernels with different
668# security feature characteristics depending on the compiler used. ("But I
669# selected CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!")
670#
671# The middle ground is to warn here so that the failed option is obvious, but
672# to let the build fail with bad compiler flags so that we can't produce a
673# kernel when there is a CONFIG and compiler mismatch.
674#
675ifdef CONFIG_CC_STACKPROTECTOR_REGULAR 661ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
676 stackp-flag := -fstack-protector 662 stackp-flag := -fstack-protector
677 ifeq ($(call cc-option, $(stackp-flag)),) 663 stackp-name := REGULAR
678 $(warning Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: \
679 -fstack-protector not supported by compiler)
680 endif
681else 664else
682ifdef CONFIG_CC_STACKPROTECTOR_STRONG 665ifdef CONFIG_CC_STACKPROTECTOR_STRONG
683 stackp-flag := -fstack-protector-strong 666 stackp-flag := -fstack-protector-strong
684 ifeq ($(call cc-option, $(stackp-flag)),) 667 stackp-name := STRONG
685 $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \
686 -fstack-protector-strong not supported by compiler)
687 endif
688else 668else
689 # Force off for distro compilers that enable stack protector by default. 669 # Force off for distro compilers that enable stack protector by default.
690 stackp-flag := $(call cc-option, -fno-stack-protector) 670 stackp-flag := $(call cc-option, -fno-stack-protector)
691endif 671endif
692endif 672endif
673# Find arch-specific stack protector compiler sanity-checking script.
674ifdef CONFIG_CC_STACKPROTECTOR
675 stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh
676 stackp-check := $(wildcard $(stackp-path))
677endif
693KBUILD_CFLAGS += $(stackp-flag) 678KBUILD_CFLAGS += $(stackp-flag)
694 679
695ifeq ($(cc-name),clang) 680ifeq ($(cc-name),clang)
@@ -1017,8 +1002,10 @@ ifneq ($(KBUILD_SRC),)
1017 fi; 1002 fi;
1018endif 1003endif
1019 1004
1020# prepare2 creates a makefile if using a separate output directory 1005# prepare2 creates a makefile if using a separate output directory.
1021prepare2: prepare3 outputmakefile asm-generic 1006# From this point forward, .config has been reprocessed, so any rules
1007# that need to depend on updated CONFIG_* values can be checked here.
1008prepare2: prepare3 prepare-compiler-check outputmakefile asm-generic
1022 1009
1023prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ 1010prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
1024 include/config/auto.conf 1011 include/config/auto.conf
@@ -1049,6 +1036,32 @@ endif
1049PHONY += prepare-objtool 1036PHONY += prepare-objtool
1050prepare-objtool: $(objtool_target) 1037prepare-objtool: $(objtool_target)
1051 1038
1039# Check for CONFIG flags that require compiler support. Abort the build
1040# after .config has been processed, but before the kernel build starts.
1041#
1042# For security-sensitive CONFIG options, we don't want to fallback and/or
1043# silently change which compiler flags will be used, since that leads to
1044# producing kernels with different security feature characteristics
1045# depending on the compiler used. (For example, "But I selected
1046# CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!")
1047PHONY += prepare-compiler-check
1048prepare-compiler-check: FORCE
1049# Make sure compiler supports requested stack protector flag.
1050ifdef stackp-name
1051 ifeq ($(call cc-option, $(stackp-flag)),)
1052 @echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
1053 $(stackp-flag) not supported by compiler >&2 && exit 1
1054 endif
1055endif
1056# Make sure compiler does not have buggy stack-protector support.
1057ifdef stackp-check
1058 ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
1059 @echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
1060 $(stackp-flag) available but compiler is broken >&2 && exit 1
1061 endif
1062endif
1063 @:
1064
1052# Generate some files 1065# Generate some files
1053# --------------------------------------------------------------------------- 1066# ---------------------------------------------------------------------------
1054 1067
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 6fce7f096b88..830ed391e7ef 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -126,14 +126,6 @@ else
126 KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args) 126 KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args)
127endif 127endif
128 128
129# Make sure compiler does not have buggy stack-protector support.
130ifdef CONFIG_CC_STACKPROTECTOR
131 cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
132 ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
133 $(warning stack-protector enabled but compiler support broken)
134 endif
135endif
136
137ifdef CONFIG_X86_X32 129ifdef CONFIG_X86_X32
138 x32_ld_ok := $(call try-run,\ 130 x32_ld_ok := $(call try-run,\
139 /bin/echo -e '1: .quad 1b' | \ 131 /bin/echo -e '1: .quad 1b' | \