diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 0e966e8f9ec7..a4eb01843c04 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -473,6 +473,24 @@ config option to 'y' no matter the dependencies. The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the situation where select forces a symbol equals to 'y'. +Adding features that need compiler support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are several features that need compiler support. The recommended way +to describe the dependency on the compiler feature is to use "depends on" +followed by a test macro. + +config CC_STACKPROTECTOR + bool "Stack Protector buffer overflow detection" + depends on $(cc-option,-fstack-protector) + ... + +If you need to expose a compiler capability to makefiles and/or C source files, +CC_HAS_ is the recommended prefix for the config option. + +config CC_HAS_STACKPROTECTOR_NONE + def_bool $(cc-option,-fno-stack-protector) + Build as module only ~~~~~~~~~~~~~~~~~~~~ To restrict a component build to module-only, qualify its config symbol diff --git a/Makefile b/Makefile index 019a5a020606..73f0bb2c7a98 100644 --- a/Makefile +++ b/Makefile @@ -442,8 +442,6 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL export KBUILD_ARFLAGS -export CC_VERSION_TEXT := $(shell $(CC) --version | head -n 1) - # When compiling out-of-tree modules, put MODVERDIR in the module # tree rather than in the kernel tree. The kernel tree might # even be read-only. @@ -514,6 +512,12 @@ ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/cc-can-link.sh $(CC)), y) export CC_CAN_LINK endif +# The expansion should be delayed until arch/$(SRCARCH)/Makefile is included. +# Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile. +# CC_VERSION_TEXT is referenced from Kconfig (so it needs export), +# and from include/config/auto.conf.cmd to detect the compiler upgrade. +CC_VERSION_TEXT = $(shell $(CC) --version | head -n 1) + ifeq ($(config-targets),1) # =========================================================================== # *config targets only - make sure prerequisites are updated, and descend @@ -523,7 +527,7 @@ ifeq ($(config-targets),1) # KBUILD_DEFCONFIG may point out an alternative default configuration # used for 'make defconfig' include arch/$(SRCARCH)/Makefile -export KBUILD_DEFCONFIG KBUILD_KCONFIG +export KBUILD_DEFCONFIG KBUILD_KCONFIG CC_VERSION_TEXT config: scripts_basic outputmakefile FORCE $(Q)$(MAKE) $(build)=scripts/kconfig $@ @@ -585,12 +589,32 @@ virt-y := virt/ endif # KBUILD_EXTMOD ifeq ($(dot-config),1) -# Read in config -include include/config/auto.conf +endif +# The all: target is the default when no target is given on the +# command line. +# This allow a user to issue only 'make' to build a kernel including modules +# Defaults to vmlinux, but the arch makefile usually adds further targets +all: vmlinux + +CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \ + $(call cc-option,-fno-tree-loop-im) \ + $(call cc-disable-warning,maybe-uninitialized,) +export CFLAGS_GCOV + +# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default +# values of the respective KBUILD_* variables +ARCH_CPPFLAGS := +ARCH_AFLAGS := +ARCH_CFLAGS := +include arch/$(SRCARCH)/Makefile + +ifeq ($(dot-config),1) ifeq ($(KBUILD_EXTMOD),) -# Read in dependencies to all Kconfig* files, make sure to run -# oldconfig if changes are detected. +# Read in dependencies to all Kconfig* files, make sure to run syncconfig if +# changes are detected. This should be included after arch/$(SRCARCH)/Makefile +# because some architectures define CROSS_COMPILE there. -include include/config/auto.conf.cmd # To avoid any implicit rule to kick in, define an empty command @@ -622,24 +646,6 @@ else include/config/auto.conf: ; endif # $(dot-config) -# The all: target is the default when no target is given on the -# command line. -# This allow a user to issue only 'make' to build a kernel including modules -# Defaults to vmlinux, but the arch makefile usually adds further targets -all: vmlinux - -CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \ - $(call cc-option,-fno-tree-loop-im) \ - $(call cc-disable-warning,maybe-uninitialized,) -export CFLAGS_GCOV CFLAGS_KCOV - -# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default -# values of the respective KBUILD_* variables -ARCH_CPPFLAGS := -ARCH_AFLAGS := -ARCH_CFLAGS := -include arch/$(SRCARCH)/Makefile - KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) @@ -680,55 +686,11 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) 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 -else -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. - 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. - ifdef stackp-check - ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) - 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 - # 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 -endif +stackp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector +stackp-flags-$(CONFIG_CC_STACKPROTECTOR) := -fstack-protector +stackp-flags-$(CONFIG_CC_STACKPROTECTOR_STRONG) := -fstack-protector-strong + +KBUILD_CFLAGS += $(stackp-flags-y) ifeq ($(cc-name),clang) KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) @@ -1112,7 +1074,7 @@ endif # 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 +prepare2: prepare3 outputmakefile asm-generic prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h \ include/config/auto.conf @@ -1138,43 +1100,6 @@ uapi-asm-generic: 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 - # 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. 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 - @: - # Generate some files # --------------------------------------------------------------------------- diff --git a/arch/Kconfig b/arch/Kconfig index 86ae4c4edd6f..ebbb45096191 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -405,6 +405,15 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +preferred-plugin-hostcc := $(if-success,[ $(gcc-version) -ge 40800 ],$(HOSTCXX),$(HOSTCC)) + +config PLUGIN_HOSTCC + string + default "$(shell,$(srctree)/scripts/gcc-plugin.sh "$(preferred-plugin-hostcc)" "$(HOSTCXX)" "$(CC)")" + help + Host compiler used to build GCC plugins. This can be $(HOSTCXX), + $(HOSTCC), or a null string if GCC plugin is unsupported. + config HAVE_GCC_PLUGINS bool help @@ -414,7 +423,7 @@ config HAVE_GCC_PLUGINS menuconfig GCC_PLUGINS bool "GCC plugins" depends on HAVE_GCC_PLUGINS - depends on !COMPILE_TEST + depends on PLUGIN_HOSTCC != "" help GCC plugins are loadable modules that provide extra features to the compiler. They are useful for runtime instrumentation and static analysis. @@ -424,7 +433,7 @@ menuconfig GCC_PLUGINS config GCC_PLUGIN_CYC_COMPLEXITY bool "Compute the cyclomatic complexity of a function" if EXPERT depends on GCC_PLUGINS - depends on !COMPILE_TEST + depends on !COMPILE_TEST # too noisy help The complexity M of a function's control flow graph is defined as: M = E - N + 2P @@ -484,6 +493,7 @@ config GCC_PLUGIN_STRUCTLEAK config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL bool "Force initialize all struct type variables passed by reference" depends on GCC_PLUGIN_STRUCTLEAK + depends on !COMPILE_TEST help Zero initialize any struct type local variable that may be passed by reference without having been initialized. @@ -491,7 +501,7 @@ config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL config GCC_PLUGIN_STRUCTLEAK_VERBOSE bool "Report forcefully initialized variables" depends on GCC_PLUGIN_STRUCTLEAK - depends on !COMPILE_TEST + depends on !COMPILE_TEST # too noisy help This option will cause a warning to be printed each time the structleak plugin finds a variable it thinks needs to be @@ -531,7 +541,7 @@ config GCC_PLUGIN_RANDSTRUCT config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE bool "Use cacheline-aware structure randomization" depends on GCC_PLUGIN_RANDSTRUCT - depends on !COMPILE_TEST + depends on !COMPILE_TEST # do not reduce test coverage help If you say Y here, the RANDSTRUCT randomization will make a best effort at restricting randomization to cacheline-sized @@ -543,13 +553,16 @@ config HAVE_CC_STACKPROTECTOR bool help An arch should select this symbol if: - - its compiler supports the -fstack-protector option - it has implemented a stack canary (e.g. __stack_chk_guard) -choice - prompt "Stack Protector buffer overflow detection" +config CC_HAS_STACKPROTECTOR_NONE + def_bool $(cc-option,-fno-stack-protector) + +config CC_STACKPROTECTOR + bool "Stack Protector buffer overflow detection" depends on HAVE_CC_STACKPROTECTOR - default CC_STACKPROTECTOR_AUTO + depends on $(cc-option,-fstack-protector) + default y help This option turns on the "stack-protector" GCC feature. This feature puts, at the beginning of functions, a canary value on @@ -559,14 +572,6 @@ choice overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. -config CC_STACKPROTECTOR_NONE - bool "None" - help - Disable "stack-protector" GCC feature. - -config CC_STACKPROTECTOR_REGULAR - bool "Regular" - help Functions will have the stack-protector canary logic added if they have an 8-byte or larger character array on the stack. @@ -578,7 +583,10 @@ config CC_STACKPROTECTOR_REGULAR by about 0.3%. config CC_STACKPROTECTOR_STRONG - bool "Strong" + bool "Strong Stack Protector" + depends on CC_STACKPROTECTOR + depends on $(cc-option,-fstack-protector-strong) + default y help Functions will have the stack-protector canary logic added in any of the following conditions: @@ -596,14 +604,6 @@ 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 HAVE_ARCH_WITHIN_STACK_FRAMES bool help diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9fd4a8ccce07..14f204c45450 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -46,6 +46,7 @@ config ARM64 select ARCH_USE_QUEUED_RWLOCKS select ARCH_SUPPORTS_MEMORY_FAILURE select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG select ARCH_SUPPORTS_NUMA_BALANCING select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select ARCH_WANT_FRAME_POINTERS diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 3c353b4715dc..45272266dafb 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -56,12 +56,6 @@ KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) -ifeq ($(cc-name),clang) -KBUILD_CFLAGS += -DCONFIG_ARCH_SUPPORTS_INT128 -else -KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128) -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index eaba5920234d..9f2b75fe2c2d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -190,7 +190,7 @@ config PPC select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER - select HAVE_GCC_PLUGINS + select HAVE_GCC_PLUGINS if GCC_VERSION >= 50200 # plugin support on gcc <= 5.1 is buggy on PPC select HAVE_GENERIC_GUP select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) select HAVE_IDE @@ -461,23 +461,9 @@ config LD_HEAD_STUB_CATCH If unsure, say "N". -config DISABLE_MPROFILE_KERNEL - bool "Disable use of mprofile-kernel for kernel tracing" - depends on PPC64 && CPU_LITTLE_ENDIAN - default y - help - Selecting this options disables use of the mprofile-kernel ABI for - kernel tracing. That will cause options such as live patching - (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to - be disabled also. - - If you have a toolchain which supports mprofile-kernel, then you can - disable this. Otherwise leave it enabled. If you're not sure, say - "Y". - config MPROFILE_KERNEL depends on PPC64 && CPU_LITTLE_ENDIAN - def_bool !DISABLE_MPROFILE_KERNEL + def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__) config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 9b52e42e581b..bd06a3ccda31 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -161,18 +161,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 endif ifdef CONFIG_MPROFILE_KERNEL - ifeq ($(shell $(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK) - CC_FLAGS_FTRACE := -pg -mprofile-kernel - KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL - else - # If the user asked for mprofile-kernel but the toolchain doesn't - # support it, emit a warning and deliberately break the build later - # with mprofile-kernel-not-supported. We would prefer to make this an - # error right here, but then the user would never be able to run - # oldconfig to change their configuration. - $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL) - CC_FLAGS_FTRACE := -mprofile-kernel-not-supported - endif + CC_FLAGS_FTRACE := -pg -mprofile-kernel endif CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index d8374f984f39..d61b0818e267 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h @@ -14,7 +14,7 @@ #include -#ifdef CC_USING_MPROFILE_KERNEL +#ifdef CONFIG_MPROFILE_KERNEL #define MODULE_ARCH_VERMAGIC_FTRACE "mprofile-kernel " #else #define MODULE_ARCH_VERMAGIC_FTRACE "" diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 1b7419579820..b8d61e019d06 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -466,7 +466,7 @@ static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs, return (unsigned long)&stubs[i]; } -#ifdef CC_USING_MPROFILE_KERNEL +#ifdef CONFIG_MPROFILE_KERNEL static bool is_mprofile_mcount_callsite(const char *name, u32 *instruction) { if (strcmp("_mcount", name)) @@ -753,7 +753,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, #ifdef CONFIG_DYNAMIC_FTRACE -#ifdef CC_USING_MPROFILE_KERNEL +#ifdef CONFIG_MPROFILE_KERNEL #define PACATOC offsetof(struct paca_struct, kernel_toc) diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index c076a32093fd..4bfbb54dee51 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -144,7 +144,7 @@ __ftrace_make_nop(struct module *mod, return -EINVAL; } -#ifdef CC_USING_MPROFILE_KERNEL +#ifdef CONFIG_MPROFILE_KERNEL /* When using -mkernel_profile there is no load to jump over */ pop = PPC_INST_NOP; @@ -188,7 +188,7 @@ __ftrace_make_nop(struct module *mod, pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op); return -EINVAL; } -#endif /* CC_USING_MPROFILE_KERNEL */ +#endif /* CONFIG_MPROFILE_KERNEL */ if (patch_instruction((unsigned int *)ip, pop)) { pr_err("Patching NOP failed.\n"); @@ -324,7 +324,7 @@ int ftrace_make_nop(struct module *mod, * They should effectively be a NOP, and follow formal constraints, * depending on the ABI. Return false if they don't. */ -#ifndef CC_USING_MPROFILE_KERNEL +#ifndef CONFIG_MPROFILE_KERNEL static int expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) { diff --git a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh index a7dd0e5d9f98..137f3376ac2b 100755 --- a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh +++ b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh @@ -24,5 +24,4 @@ echo -e "#include \nnotrace int func() { return 0; }" | \ 2> /dev/null | grep -q "_mcount" && \ exit 1 -echo "OK" exit 0 diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h index f312813f39d8..992955685874 100644 --- a/arch/sh/include/asm/vmlinux.lds.h +++ b/arch/sh/include/asm/vmlinux.lds.h @@ -7,9 +7,9 @@ #ifdef CONFIG_DWARF_UNWINDER #define DWARF_EH_FRAME \ .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_eh_frame) = .; \ + __start_eh_frame = .; \ *(.eh_frame) \ - VMLINUX_SYMBOL(__stop_eh_frame) = .; \ + __stop_eh_frame = .; \ } #else #define DWARF_EH_FRAME diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 297789aef9fa..455a670ab239 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -130,7 +130,7 @@ config X86 select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64 select HAVE_ARCH_VMAP_STACK if X86_64 select HAVE_ARCH_WITHIN_STACK_FRAMES - select HAVE_CC_STACKPROTECTOR + select HAVE_CC_STACKPROTECTOR if CC_HAS_SANE_STACKPROTECTOR select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL select HAVE_CONTEXT_TRACKING if X86_64 @@ -346,6 +346,15 @@ config PGTABLE_LEVELS default 2 source "init/Kconfig" + +config CC_HAS_SANE_STACKPROTECTOR + bool + default $(success,$(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC)) if 64BIT + default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC)) + help + We have to make sure stack protector is unconditionally disabled if + the compiler produces broken code. + source "kernel/Kconfig.freezer" menu "Processor type and features" diff --git a/include/linux/linkage.h b/include/linux/linkage.h index f68db9e450eb..d7618c41f74c 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -24,16 +24,16 @@ #ifndef cond_syscall #define cond_syscall(x) asm( \ - ".weak " VMLINUX_SYMBOL_STR(x) "\n\t" \ - ".set " VMLINUX_SYMBOL_STR(x) "," \ - VMLINUX_SYMBOL_STR(sys_ni_syscall)) + ".weak " __stringify(x) "\n\t" \ + ".set " __stringify(x) "," \ + __stringify(sys_ni_syscall)) #endif #ifndef SYSCALL_ALIAS #define SYSCALL_ALIAS(alias, name) asm( \ - ".globl " VMLINUX_SYMBOL_STR(alias) "\n\t" \ - ".set " VMLINUX_SYMBOL_STR(alias) "," \ - VMLINUX_SYMBOL_STR(name)) + ".globl " __stringify(alias) "\n\t" \ + ".set " __stringify(alias) "," \ + __stringify(name)) #endif #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE) diff --git a/init/Kconfig b/init/Kconfig index d2b8b2ea097e..5a52f07259a2 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -8,6 +8,21 @@ config DEFCONFIG_LIST default ARCH_DEFCONFIG default "arch/$(ARCH)/defconfig" +config CC_IS_GCC + def_bool $(success,$(CC) --version | head -n 1 | grep -q gcc) + +config GCC_VERSION + int + default $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//') if CC_IS_GCC + default 0 + +config CC_IS_CLANG + def_bool $(success,$(CC) --version | head -n 1 | grep -q clang) + +config CLANG_VERSION + int + default $(shell,$(srctree)/scripts/clang-version.sh $(CC)) + config CONSTRUCTORS bool depends on !UML diff --git a/kernel/gcov/Kconfig b/kernel/gcov/Kconfig index 1276aabaab55..1e3823fa799b 100644 --- a/kernel/gcov/Kconfig +++ b/kernel/gcov/Kconfig @@ -53,23 +53,16 @@ config GCOV_PROFILE_ALL choice prompt "Specify GCOV format" depends on GCOV_KERNEL - default GCOV_FORMAT_AUTODETECT ---help--- - The gcov format is usually determined by the GCC version, but there are + The gcov format is usually determined by the GCC version, and the + default is chosen according to your GCC version. However, there are exceptions where format changes are integrated in lower-version GCCs. - In such a case use this option to adjust the format used in the kernel - accordingly. - - If unsure, choose "Autodetect". - -config GCOV_FORMAT_AUTODETECT - bool "Autodetect" - ---help--- - Select this option to use the format that corresponds to your GCC - version. + In such a case, change this option to adjust the format used in the + kernel accordingly. config GCOV_FORMAT_3_4 bool "GCC 3.4 format" + depends on CC_IS_GCC && GCC_VERSION < 40700 ---help--- Select this option to use the format defined by GCC 3.4. diff --git a/kernel/gcov/Makefile b/kernel/gcov/Makefile index c6c50e5c680e..ff06d64df397 100644 --- a/kernel/gcov/Makefile +++ b/kernel/gcov/Makefile @@ -4,5 +4,3 @@ ccflags-y := -DSRCTREE='"$(srctree)"' -DOBJTREE='"$(objtree)"' obj-y := base.o fs.o obj-$(CONFIG_GCOV_FORMAT_3_4) += gcc_3_4.o obj-$(CONFIG_GCOV_FORMAT_4_7) += gcc_4_7.o -obj-$(CONFIG_GCOV_FORMAT_AUTODETECT) += $(call cc-ifversion, -lt, 0407, \ - gcc_3_4.o, gcc_4_7.o) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index eb885942eb0f..d543c65ce0eb 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -736,12 +736,15 @@ config ARCH_HAS_KCOV only for x86_64. KCOV requires testing on other archs, and most likely disabling of instrumentation for some early boot code. +config CC_HAS_SANCOV_TRACE_PC + def_bool $(cc-option,-fsanitize-coverage=trace-pc) + config KCOV bool "Code coverage for fuzzing" depends on ARCH_HAS_KCOV + depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS select DEBUG_FS - select GCC_PLUGINS if !COMPILE_TEST - select GCC_PLUGIN_SANCOV if !COMPILE_TEST + select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC help KCOV exposes kernel code coverage information in a form suitable for coverage-guided fuzzing (randomized testing). @@ -755,7 +758,7 @@ config KCOV config KCOV_ENABLE_COMPARISONS bool "Enable comparison operands collection by KCOV" depends on KCOV - default n + depends on $(cc-option,-fsanitize-coverage=trace-cmp) help KCOV also exposes operands of every comparison in the instrumented code along with operand sizes and PCs of the comparison instructions. @@ -765,7 +768,7 @@ config KCOV_ENABLE_COMPARISONS config KCOV_INSTRUMENT_ALL bool "Instrument all code by default" depends on KCOV - default y if KCOV + default y help If you are doing generic system call fuzzing (like e.g. syzkaller), then you will want to instrument the whole kernel and you should diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index bf7c0c9fa3a4..dad5583451af 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -25,3 +25,6 @@ cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) # $(ld-option,) # Return y if the linker supports , n otherwise ld-option = $(success,$(LD) -v $(1)) + +# gcc version including patch level +gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//') diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 7f5c86246138..c961b9a65d11 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -1,84 +1,37 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_GCC_PLUGINS - __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) - PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") +gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so - SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so - - gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so - - gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += -DLATENT_ENTROPY_PLUGIN - ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY +gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += -DLATENT_ENTROPY_PLUGIN +ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable - endif - - ifdef CONFIG_GCC_PLUGIN_SANCOV - ifeq ($(strip $(CFLAGS_KCOV)),) - # It is needed because of the gcc-plugin.sh and gcc version checks. - gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so - - ifneq ($(PLUGINCC),) - CFLAGS_KCOV := $(SANCOV_PLUGIN) - else - $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler) - endif - endif - endif - - gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN - - gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN - gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode - - GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) - - export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR - export SANCOV_PLUGIN DISABLE_LATENT_ENTROPY_PLUGIN - - ifneq ($(PLUGINCC),) - # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. - GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) - endif - - KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) - GCC_PLUGIN := $(gcc-plugin-y) - GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y) endif -# If plugins aren't supported, abort the build before hard-to-read compiler -# errors start getting spewed by the main build. -PHONY += gcc-plugins-check -gcc-plugins-check: FORCE -ifdef CONFIG_GCC_PLUGINS - ifeq ($(PLUGINCC),) - ifneq ($(GCC_PLUGINS_CFLAGS),) - # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing - # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 have - # issues with 64-bit targets. - ifeq ($(ARCH),powerpc) - ifeq ($(call cc-ifversion, -le, 0501, y), y) - @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1 - endif - endif - ifeq ($(call cc-ifversion, -ge, 0405, y), y) - $(Q)$(srctree)/scripts/gcc-plugin.sh --show-error "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" || true - @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1 - else - @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc version does not support plugins, you should upgrade it to at least gcc 4.5" >&2 && exit 1 - endif - endif - endif -endif - @: +gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so +gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode + +GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) + +export GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR +export DISABLE_LATENT_ENTROPY_PLUGIN + +# sancov_plugin.so can be only in CFLAGS_KCOV because avoid duplication. +GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) + +KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) +GCC_PLUGIN := $(gcc-plugin-y) +GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y) # Actually do the build, if requested. PHONY += gcc-plugins -gcc-plugins: scripts_basic gcc-plugins-check +gcc-plugins: scripts_basic ifdef CONFIG_GCC_PLUGINS $(Q)$(MAKE) $(build)=scripts/gcc-plugins endif diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov index 5cc72037e423..3d61c4bfcbee 100644 --- a/scripts/Makefile.kcov +++ b/scripts/Makefile.kcov @@ -1,7 +1,9 @@ ifdef CONFIG_KCOV -CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) -ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y) -CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,) -endif + +kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc +kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp +kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so + +export CFLAGS_KCOV := $(kcov-flags-y) endif diff --git a/scripts/clang-version.sh b/scripts/clang-version.sh index 9780efa56980..dbf0a31eb111 100755 --- a/scripts/clang-version.sh +++ b/scripts/clang-version.sh @@ -10,24 +10,14 @@ # clang-5.0.1 etc. # -if [ "$1" = "-p" ] ; then - with_patchlevel=1; - shift; -fi - compiler="$*" -if [ ${#compiler} -eq 0 ]; then - echo "Error: No compiler specified." - printf "Usage:\n\t$0 \n" +if !( $compiler --version | grep -q clang) ; then + echo 0 exit 1 fi MAJOR=$(echo __clang_major__ | $compiler -E -x c - | tail -n 1) MINOR=$(echo __clang_minor__ | $compiler -E -x c - | tail -n 1) -if [ "x$with_patchlevel" != "x" ] ; then - PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1) - printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL -else - printf "%02d%02d\\n" $MAJOR $MINOR -fi +PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1) +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index e2ff425f4c7e..326254653bd0 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +PLUGINCC := $(CONFIG_PLUGIN_HOSTCC:"%"=%) GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) ifeq ($(PLUGINCC),$(HOSTCC)) @@ -13,10 +14,6 @@ else export HOST_EXTRACXXFLAGS endif -ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN)) - GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN)) -endif - export HOSTLIBS $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh index 6b2aeefb9cd3..f5c119495254 100755 --- a/scripts/gcc-x86_32-has-stack-protector.sh +++ b/scripts/gcc-x86_32-has-stack-protector.sh @@ -1,9 +1,4 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" -if [ "$?" -eq "0" ] ; then - echo y -else - echo n -fi +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh index 4a48bdcd4d6b..3755af0cd9f7 100755 --- a/scripts/gcc-x86_64-has-stack-protector.sh +++ b/scripts/gcc-x86_64-has-stack-protector.sh @@ -2,8 +2,3 @@ # SPDX-License-Identifier: GPL-2.0 echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" -if [ "$?" -eq "0" ] ; then - echo y -else - echo n -fi diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index a2e83ab17de3..4686531e2f8c 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -165,10 +165,10 @@ sub read_kconfig { my $last_source = ""; # Check for any environment variables used - while ($source =~ /\$(\w+)/ && $last_source ne $source) { + while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) { my $env = $1; $last_source = $source; - $source =~ s/\$$env/$ENV{$env}/; + $source =~ s/\$\($env\)/$ENV{$env}/; } open(my $kinfile, '<', $source) || die "Can't open $kconfig";