From 6b90bd4ba40b38dc13c2782469c1c77e4ed79915 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Tue, 24 May 2016 00:09:38 +0200 Subject: GCC plugin infrastructure This patch allows to build the whole kernel with GCC plugins. It was ported from grsecurity/PaX. The infrastructure supports building out-of-tree modules and building in a separate directory. Cross-compilation is supported too. Currently the x86, arm, arm64 and uml architectures enable plugins. The directory of the gcc plugins is scripts/gcc-plugins. You can use a file or a directory there. The plugins compile with these options: * -fno-rtti: gcc is compiled with this option so the plugins must use it too * -fno-exceptions: this is inherited from gcc too * -fasynchronous-unwind-tables: this is inherited from gcc too * -ggdb: it is useful for debugging a plugin (better backtrace on internal errors) * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h) * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version variable, plugin-version.h) The infrastructure introduces a new Makefile target called gcc-plugins. It supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++). This script also checks the availability of the included headers in scripts/gcc-plugins/gcc-common.h. The gcc-common.h header contains frequently included headers for GCC plugins and it has a compatibility layer for the supported gcc versions. The gcc-generate-*-pass.h headers automatically generate the registration structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes. Note that 'make clean' keeps the *.so files (only the distclean or mrproper targets clean all) because they are needed for out-of-tree modules. Based on work created by the PaX Team. Signed-off-by: Emese Revfy Acked-by: Kees Cook Signed-off-by: Michal Marek --- Makefile | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 0f70de6..20fcf4b 100644 --- a/Makefile +++ b/Makefile @@ -552,7 +552,7 @@ ifeq ($(KBUILD_EXTMOD),) # in parallel PHONY += scripts scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ - asm-generic + asm-generic gcc-plugins $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -631,6 +631,15 @@ endif # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +PHONY += gcc-plugins +gcc-plugins: scripts_basic +ifdef CONFIG_GCC_PLUGINS + $(Q)$(MAKE) $(build)=scripts/gcc-plugins +endif + @: + +include scripts/Makefile.gcc-plugins + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -1026,7 +1035,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ archprepare: archheaders archscripts prepare1 scripts_basic -prepare0: archprepare +prepare0: archprepare gcc-plugins $(Q)$(MAKE) $(build)=. # All the preparing.. @@ -1507,6 +1516,7 @@ clean: $(clean-dirs) -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ -o -name modules.builtin -o -name '.tmp_*.o.*' \ + -o -name '*.c.[012]*.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # Generate tags for editors -- cgit v1.1 From 543c37cb165049c3be24a0d4733e67caa2b33eef Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Tue, 24 May 2016 00:11:37 +0200 Subject: Add sancov plugin The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call at the start of basic blocks. This plugin is a helper plugin for the kcov feature. It supports all gcc versions with plugin support (from gcc-4.5 on). It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov (https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296). Signed-off-by: Emese Revfy Acked-by: Kees Cook Signed-off-by: Michal Marek --- Makefile | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 20fcf4b..c3d494b 100644 --- a/Makefile +++ b/Makefile @@ -369,7 +369,7 @@ LDFLAGS_MODULE = CFLAGS_KERNEL = AFLAGS_KERNEL = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized -CFLAGS_KCOV = -fsanitize-coverage=trace-pc +CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) # Use USERINCLUDE when you must reference the UAPI directories only. @@ -691,14 +691,6 @@ endif endif KBUILD_CFLAGS += $(stackp-flag) -ifdef CONFIG_KCOV - ifeq ($(call cc-option, $(CFLAGS_KCOV)),) - $(warning Cannot use CONFIG_KCOV: \ - -fsanitize-coverage=trace-pc is not supported by compiler) - CFLAGS_KCOV = - endif -endif - ifeq ($(cc-name),clang) KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,) -- cgit v1.1 From dc33db7c338e1a7a4a7cb94d73745c8ca54b1ac8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 15 Jun 2016 17:45:44 +0200 Subject: Kbuild: avoid duplicate include path arch/$(hdr-arch)/include/generated/uapi is included twice in the header search path, which is unnecessary, so this changes the top-level Makefile to drop the second instance by filtering out everything from USERINCLUDE that was already part of LINUXINCLUDE. This should have very little effect other than making the 'make V=1' output slightly smaller and making the build time faster by a miniscule amount, but it seems to be cleaner. Signed-off-by: Arnd Bergmann Signed-off-by: Michal Marek --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index c3d494b..337686d 100644 --- a/Makefile +++ b/Makefile @@ -387,8 +387,9 @@ LINUXINCLUDE := \ -Iarch/$(hdr-arch)/include/generated/uapi \ -Iarch/$(hdr-arch)/include/generated \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -Iinclude \ - $(USERINCLUDE) + -Iinclude + +LINUXINCLUDE += $(filter-out $(LINUXINCLUDE),$(USERINCLUDE)) KBUILD_CPPFLAGS := -D__KERNEL__ -- cgit v1.1 From 3308b28569ba3327419658edd194a967e3fd51e2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 15 Jun 2016 17:45:45 +0200 Subject: Kbuild: always prefix objtree in LINUXINCLUDE When $(LINUXINCLUDE) is added to the cflags of a target that normall doesn't have it (e.g. HOSTCFLAGS), each entry in the list is expanded so that we search both $(objtree) and $(srctree), which is a bit silly, as we already know which of the two we want for each entry in LINUXINCLUDE. Also, a follow-up patch changes the behavior so we only look in $(srctree) for manually added include path, and that breaks finding the generated headers. This adds an explicit $(objtree) for each tree that we want to look for generated files. Signed-off-by: Arnd Bergmann Signed-off-by: Michal Marek --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 337686d..64684b1 100644 --- a/Makefile +++ b/Makefile @@ -375,19 +375,19 @@ CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE := \ -I$(srctree)/arch/$(hdr-arch)/include/uapi \ - -Iarch/$(hdr-arch)/include/generated/uapi \ + -I$(objtree)/arch/$(hdr-arch)/include/generated/uapi \ -I$(srctree)/include/uapi \ - -Iinclude/generated/uapi \ + -I$(objtree)/include/generated/uapi \ -include $(srctree)/include/linux/kconfig.h # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := \ -I$(srctree)/arch/$(hdr-arch)/include \ - -Iarch/$(hdr-arch)/include/generated/uapi \ - -Iarch/$(hdr-arch)/include/generated \ + -I$(objtree)/arch/$(hdr-arch)/include/generated/uapi \ + -I$(objtree)/arch/$(hdr-arch)/include/generated \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -Iinclude + -I$(objtree)/include LINUXINCLUDE += $(filter-out $(LINUXINCLUDE),$(USERINCLUDE)) -- cgit v1.1 From ddea05fa148b4d8e66498e522a616d87f9cf81e3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 4 Jul 2016 16:39:35 +0200 Subject: kbuild: make samples depend on headers_install Olof's build test setup keeps failing to compile arm64 kernels because of a toolchain that uses outdated kernel headers: /work/build/batch/samples/seccomp/bpf-fancy.c:13:27: fatal error: linux/seccomp.h: No such file or directory This is of course something he could change, but it also indicates that others may run into the same problem. Running 'make headers_install' avoids the issue by ensuring that the kernel headers are put into the $(objdir)/usr/include path before we build the samples. The same problem happened for the Documentation build in the past and was fixed up with commit 8e2faea877eb ("Make Documenation depend on headers_install"). This adds an identical Makefile dependency for the samples/ subdirectory. Signed-off-by: Arnd Bergmann Signed-off-by: Michal Marek --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 64684b1..7aa6f8c 100644 --- a/Makefile +++ b/Makefile @@ -1620,7 +1620,7 @@ endif $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(build)=$(build-dir) # Make sure the latest headers are built for Documentation -Documentation/: headers_install +Documentation/ samples/: headers_install %/: prepare scripts FORCE $(cmd_crmodverdir) $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ -- cgit v1.1 From 228d96c603cf53e32f672c0e459d2adbc5a4609a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 26 Jul 2016 14:26:20 -0700 Subject: 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 Signed-off-by: Michal Marek --- Makefile | 67 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 27 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 7aa6f8c..08aac0a 100644 --- a/Makefile +++ b/Makefile @@ -655,41 +655,26 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -# Handle stack protector mode. -# -# Since kbuild can potentially perform two passes (first with the old -# .config values and then with updated .config values), we cannot error out -# if a desired compiler option is unsupported. If we were to error, kbuild -# could never get to the second pass and actually notice that we changed -# the option to something that was supported. -# -# Additionally, we don't want to fallback and/or silently change which compiler -# flags will be used, since that leads to producing kernels with different -# security feature characteristics depending on the compiler used. ("But I -# selected CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!") -# -# The middle ground is to warn here so that the failed option is obvious, but -# to let the build fail with bad compiler flags so that we can't produce a -# kernel when there is a CONFIG and compiler mismatch. -# +# 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_REGULAR stackp-flag := -fstack-protector - ifeq ($(call cc-option, $(stackp-flag)),) - $(warning Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: \ - -fstack-protector not supported by compiler) - endif + stackp-name := REGULAR else ifdef CONFIG_CC_STACKPROTECTOR_STRONG stackp-flag := -fstack-protector-strong - ifeq ($(call cc-option, $(stackp-flag)),) - $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ - -fstack-protector-strong not supported by compiler) - endif + stackp-name := STRONG else # Force off for distro compilers that enable stack protector by default. stackp-flag := $(call cc-option, -fno-stack-protector) endif endif +# Find arch-specific stack protector compiler sanity-checking script. +ifdef CONFIG_CC_STACKPROTECTOR + stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh + stackp-check := $(wildcard $(stackp-path)) +endif KBUILD_CFLAGS += $(stackp-flag) ifeq ($(cc-name),clang) @@ -1017,8 +1002,10 @@ ifneq ($(KBUILD_SRC),) fi; endif -# prepare2 creates a makefile if using a separate output directory -prepare2: prepare3 outputmakefile asm-generic +# prepare2 creates a makefile if using a separate output directory. +# From this point forward, .config has been reprocessed, so any rules +# that need to depend on updated CONFIG_* values can be checked here. +prepare2: prepare3 prepare-compiler-check outputmakefile asm-generic prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ include/config/auto.conf @@ -1049,6 +1036,32 @@ endif PHONY += prepare-objtool prepare-objtool: $(objtool_target) +# Check for CONFIG flags that require compiler support. Abort the build +# after .config has been processed, but before the kernel build starts. +# +# For security-sensitive CONFIG options, we don't want to fallback and/or +# silently change which compiler flags will be used, since that leads to +# producing kernels with different security feature characteristics +# depending on the compiler used. (For example, "But I selected +# CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!") +PHONY += prepare-compiler-check +prepare-compiler-check: FORCE +# Make sure compiler supports requested stack protector flag. +ifdef stackp-name + 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 +# Make sure compiler does not have buggy stack-protector support. +ifdef stackp-check + ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) + @echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \ + $(stackp-flag) available but compiler is broken >&2 && exit 1 + endif +endif + @: + # Generate some files # --------------------------------------------------------------------------- -- cgit v1.1