Pull gcc plugin cleanups from Kees Cook: - Kconfig and Makefile clean-ups (Masahiro Yamada, Kees Cook) - gcc-common.h definition clean-ups (Alexander Popov) * tag 'gcc-plugin-cleanup-v4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: gcc-plugins: Clean up the cgraph_create_edge* macros gcc-plugins: Regularize Makefile.gcc-plugins gcc-plugins: split out Kconfig entries to scripts/gcc-plugins/Kconfig gcc-plugins: remove unused GCC_PLUGIN_SUBDIR
Showing the changes to scripts (4 of 5 files). Show all
Unified · Split
| @@ -1,33 +1,44 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | |||
| 2 | gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so | 3 | gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so |
| 3 | 4 | ||
| 4 | gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so | 5 | gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so |
| 5 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += -DLATENT_ENTROPY_PLUGIN | 6 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \ |
| 7 | += -DLATENT_ENTROPY_PLUGIN | ||
| 6 | ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY | 8 | ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY |
| 7 | DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable | 9 | DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable |
| 8 | endif | 10 | endif |
| 11 | export DISABLE_LATENT_ENTROPY_PLUGIN | ||
| 9 | 12 | ||
| 10 | gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so | 13 | gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so |
| 14 | |||
| 11 | gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so | 15 | gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so |
| 12 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose | 16 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \ |
| 13 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all | 17 | += -fplugin-arg-structleak_plugin-verbose |
| 14 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN | 18 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \ |
| 19 | += -fplugin-arg-structleak_plugin-byref-all | ||
| 20 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ | ||
| 21 | += -DSTRUCTLEAK_PLUGIN | ||
| 15 | 22 | ||
| 16 | gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so | 23 | gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so |
| 17 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN | 24 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ |
| 18 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode | 25 | += -DRANDSTRUCT_PLUGIN |
| 26 | gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \ | ||
| 27 | += -fplugin-arg-randomize_layout_plugin-performance-mode | ||
| 19 | 28 | ||
| 29 | # All the plugin CFLAGS are collected here in case a build target needs to | ||
| 30 | # filter them out of the KBUILD_CFLAGS. | ||
| 20 | GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) | 31 | GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) |
| 21 | 32 | # The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here. | |
| 22 | export GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR | ||
| 23 | export DISABLE_LATENT_ENTROPY_PLUGIN | ||
| 24 | |||
| 25 | # sancov_plugin.so can be only in CFLAGS_KCOV because avoid duplication. | ||
| 26 | GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) | 33 | GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) |
| 34 | export GCC_PLUGINS_CFLAGS | ||
| 27 | 35 | ||
| 36 | # Add the flags to the build! | ||
| 28 | KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) | 37 | KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
| 38 | |||
| 39 | # All enabled GCC plugins are collected here for building below. | ||
| 29 | GCC_PLUGIN := $(gcc-plugin-y) | 40 | GCC_PLUGIN := $(gcc-plugin-y) |
| 30 | GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y) | 41 | export GCC_PLUGIN |
| 31 | 42 | ||
| 32 | # Actually do the build, if requested. | 43 | # Actually do the build, if requested. |
| 33 | PHONY += gcc-plugins | 44 | PHONY += gcc-plugins |
| @@ -0,0 +1,142 @@ | |||
| 1 | preferred-plugin-hostcc := $(if-success,[ $(gcc-version) -ge 40800 ],$(HOSTCXX),$(HOSTCC)) | ||
| 2 | |||
| 3 | config PLUGIN_HOSTCC | ||
| 4 | string | ||
| 5 | default "$(shell,$(srctree)/scripts/gcc-plugin.sh "$(preferred-plugin-hostcc)" "$(HOSTCXX)" "$(CC)")" | ||
| 6 | help | ||
| 7 | Host compiler used to build GCC plugins. This can be $(HOSTCXX), | ||
| 8 | $(HOSTCC), or a null string if GCC plugin is unsupported. | ||
| 9 | |||
| 10 | config HAVE_GCC_PLUGINS | ||
| 11 | bool | ||
| 12 | help | ||
| 13 | An arch should select this symbol if it supports building with | ||
| 14 | GCC plugins. | ||
| 15 | |||
| 16 | menuconfig GCC_PLUGINS | ||
| 17 | bool "GCC plugins" | ||
| 18 | depends on HAVE_GCC_PLUGINS | ||
| 19 | depends on PLUGIN_HOSTCC != "" | ||
| 20 | help | ||
| 21 | GCC plugins are loadable modules that provide extra features to the | ||
| 22 | compiler. They are useful for runtime instrumentation and static analysis. | ||
| 23 | |||
| 24 | See Documentation/gcc-plugins.txt for details. | ||
| 25 | |||
| 26 | if GCC_PLUGINS | ||
| 27 | |||
| 28 | config GCC_PLUGIN_CYC_COMPLEXITY | ||
| 29 | bool "Compute the cyclomatic complexity of a function" if EXPERT | ||
| 30 | depends on !COMPILE_TEST # too noisy | ||
| 31 | help | ||
| 32 | The complexity M of a function's control flow graph is defined as: | ||
| 33 | M = E - N + 2P | ||
| 34 | where | ||
| 35 | |||
| 36 | E = the number of edges | ||
| 37 | N = the number of nodes | ||
| 38 | P = the number of connected components (exit nodes). | ||
| 39 | |||
| 40 | Enabling this plugin reports the complexity to stderr during the | ||
| 41 | build. It mainly serves as a simple example of how to create a | ||
| 42 | gcc plugin for the kernel. | ||
| 43 | |||
| 44 | config GCC_PLUGIN_SANCOV | ||
| 45 | bool | ||
| 46 | help | ||
| 47 | This plugin inserts a __sanitizer_cov_trace_pc() call at the start of | ||
| 48 | basic blocks. It supports all gcc versions with plugin support (from | ||
| 49 | gcc-4.5 on). It is based on the commit "Add fuzzing coverage support" | ||
| 50 | by Dmitry Vyukov <dvyukov@google.com>. | ||
| 51 | |||
| 52 | config GCC_PLUGIN_LATENT_ENTROPY | ||
| 53 | bool "Generate some entropy during boot and runtime" | ||
| 54 | help | ||
| 55 | By saying Y here the kernel will instrument some kernel code to | ||
| 56 | extract some entropy from both original and artificially created | ||
| 57 | program state. This will help especially embedded systems where | ||
| 58 | there is little 'natural' source of entropy normally. The cost | ||
| 59 | is some slowdown of the boot process (about 0.5%) and fork and | ||
| 60 | irq processing. | ||
| 61 | |||
| 62 | Note that entropy extracted this way is not cryptographically | ||
| 63 | secure! | ||
| 64 | |||
| 65 | This plugin was ported from grsecurity/PaX. More information at: | ||
| 66 | * https://grsecurity.net/ | ||
| 67 | * https://pax.grsecurity.net/ | ||
| 68 | |||
| 69 | config GCC_PLUGIN_STRUCTLEAK | ||
| 70 | bool "Force initialization of variables containing userspace addresses" | ||
| 71 | # Currently STRUCTLEAK inserts initialization out of live scope of | ||
| 72 | # variables from KASAN point of view. This leads to KASAN false | ||
| 73 | # positive reports. Prohibit this combination for now. | ||
| 74 | depends on !KASAN_EXTRA | ||
| 75 | help | ||
| 76 | This plugin zero-initializes any structures containing a | ||
| 77 | __user attribute. This can prevent some classes of information | ||
| 78 | exposures. | ||
| 79 | |||
| 80 | This plugin was ported from grsecurity/PaX. More information at: | ||
| 81 | * https://grsecurity.net/ | ||
| 82 | * https://pax.grsecurity.net/ | ||
| 83 | |||
| 84 | config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL | ||
| 85 | bool "Force initialize all struct type variables passed by reference" | ||
| 86 | depends on GCC_PLUGIN_STRUCTLEAK | ||
| 87 | depends on !COMPILE_TEST | ||
| 88 | help | ||
| 89 | Zero initialize any struct type local variable that may be passed by | ||
| 90 | reference without having been initialized. | ||
| 91 | |||
| 92 | config GCC_PLUGIN_STRUCTLEAK_VERBOSE | ||
| 93 | bool "Report forcefully initialized variables" | ||
| 94 | depends on GCC_PLUGIN_STRUCTLEAK | ||
| 95 | depends on !COMPILE_TEST # too noisy | ||
| 96 | help | ||
| 97 | This option will cause a warning to be printed each time the | ||
| 98 | structleak plugin finds a variable it thinks needs to be | ||
| 99 | initialized. Since not all existing initializers are detected | ||
| 100 | by the plugin, this can produce false positive warnings. | ||
| 101 | |||
| 102 | config GCC_PLUGIN_RANDSTRUCT | ||
| 103 | bool "Randomize layout of sensitive kernel structures" | ||
| 104 | select MODVERSIONS if MODULES | ||
| 105 | help | ||
| 106 | If you say Y here, the layouts of structures that are entirely | ||
| 107 | function pointers (and have not been manually annotated with | ||
| 108 | __no_randomize_layout), or structures that have been explicitly | ||
| 109 | marked with __randomize_layout, will be randomized at compile-time. | ||
| 110 | This can introduce the requirement of an additional information | ||
| 111 | exposure vulnerability for exploits targeting these structure | ||
| 112 | types. | ||
| 113 | |||
| 114 | Enabling this feature will introduce some performance impact, | ||
| 115 | slightly increase memory usage, and prevent the use of forensic | ||
| 116 | tools like Volatility against the system (unless the kernel | ||
| 117 | source tree isn't cleaned after kernel installation). | ||
| 118 | |||
| 119 | The seed used for compilation is located at | ||
| 120 | scripts/gcc-plgins/randomize_layout_seed.h. It remains after | ||
| 121 | a make clean to allow for external modules to be compiled with | ||
| 122 | the existing seed and will be removed by a make mrproper or | ||
| 123 | make distclean. | ||
| 124 | |||
| 125 | Note that the implementation requires gcc 4.7 or newer. | ||
| 126 | |||
| 127 | This plugin was ported from grsecurity/PaX. More information at: | ||
| 128 | * https://grsecurity.net/ | ||
| 129 | * https://pax.grsecurity.net/ | ||
| 130 | |||
| 131 | config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE | ||
| 132 | bool "Use cacheline-aware structure randomization" | ||
| 133 | depends on GCC_PLUGIN_RANDSTRUCT | ||
| 134 | depends on !COMPILE_TEST # do not reduce test coverage | ||
| 135 | help | ||
| 136 | If you say Y here, the RANDSTRUCT randomization will make a | ||
| 137 | best effort at restricting randomization to cacheline-sized | ||
| 138 | groups of elements. It will further not randomize bitfields | ||
| 139 | in structures. This reduces the performance hit of RANDSTRUCT | ||
| 140 | at the cost of weakened randomization. | ||
| 141 | |||
| 142 | endif | ||
| @@ -14,8 +14,6 @@ else · 13 unmodified lines | |||
| 14 | export HOST_EXTRACXXFLAGS | 14 | export HOST_EXTRACXXFLAGS |
| 15 | endif | 15 | endif |
| 16 | 16 | ||
| 17 | export HOSTLIBS | ||
| 18 | |||
| 19 | $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h | 17 | $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h |
| 20 | quiet_cmd_create_randomize_layout_seed = GENSEED $@ | 18 | quiet_cmd_create_randomize_layout_seed = GENSEED $@ |
| 21 | cmd_create_randomize_layout_seed = \ | 19 | cmd_create_randomize_layout_seed = \ |
| @@ -29,7 +27,4 @@ always := $($(HOSTLIBS)-y) · 7 unmodified lines | |||
| 29 | 27 | ||
| 30 | $(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o)) | 28 | $(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o)) |
| 31 | 29 | ||
| 32 | subdir-y := $(GCC_PLUGIN_SUBDIR) | ||
| 33 | subdir- += $(GCC_PLUGIN_SUBDIR) | ||
| 34 | |||
| 35 | clean-files += *.so | 30 | clean-files += *.so |
| @@ -392,13 +392,6 @@ static inline struct cgraph_node *cgraph_alias_target(struct cgraph_node *n) · 391 unmodified lines | |||
| 392 | } | 392 | } |
| 393 | #endif | 393 | #endif |
| 394 | 394 | ||
| 395 | #if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION <= 4009 | ||
| 396 | #define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ | ||
| 397 | cgraph_create_edge((caller), (callee), (call_stmt), (count), (freq)) | ||
| 398 | #define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \ | ||
| 399 | cgraph_create_edge_including_clones((caller), (callee), (old_call_stmt), (call_stmt), (count), (freq), (reason)) | ||
| 400 | #endif | ||
| 401 | |||
| 402 | #if BUILDING_GCC_VERSION <= 4008 | 395 | #if BUILDING_GCC_VERSION <= 4008 |
| 403 | #define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) | 396 | #define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) |
| 404 | #define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN) | 397 | #define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN) |
| @@ -723,10 +716,23 @@ static inline const char *get_decl_section_name(const_tree decl) · 318 unmodified lines | |||
| 723 | #define varpool_get_node(decl) varpool_node::get(decl) | 716 | #define varpool_get_node(decl) varpool_node::get(decl) |
| 724 | #define dump_varpool_node(file, node) (node)->dump(file) | 717 | #define dump_varpool_node(file, node) (node)->dump(file) |
| 725 | 718 | ||
| 726 | #define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ | 719 | #if BUILDING_GCC_VERSION >= 8000 |
| 720 | #define cgraph_create_edge(caller, callee, call_stmt, count, freq) \ | ||
| 721 | (caller)->create_edge((callee), (call_stmt), (count)) | ||
| 722 | |||
| 723 | #define cgraph_create_edge_including_clones(caller, callee, \ | ||
| 724 | old_call_stmt, call_stmt, count, freq, reason) \ | ||
| 725 | (caller)->create_edge_including_clones((callee), \ | ||
| 726 | (old_call_stmt), (call_stmt), (count), (reason)) | ||
| 727 | #else | ||
| 728 | #define cgraph_create_edge(caller, callee, call_stmt, count, freq) \ | ||
| 727 | (caller)->create_edge((callee), (call_stmt), (count), (freq)) | 729 | (caller)->create_edge((callee), (call_stmt), (count), (freq)) |
| 728 | #define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \ | 730 | |
| 729 | (caller)->create_edge_including_clones((callee), (old_call_stmt), (call_stmt), (count), (freq), (reason)) | 731 | #define cgraph_create_edge_including_clones(caller, callee, \ |
| 732 | old_call_stmt, call_stmt, count, freq, reason) \ | ||
| 733 | (caller)->create_edge_including_clones((callee), \ | ||
| 734 | (old_call_stmt), (call_stmt), (count), (freq), (reason)) | ||
| 735 | #endif | ||
| 730 | 736 | ||
| 731 | typedef struct cgraph_node *cgraph_node_ptr; | 737 | typedef struct cgraph_node *cgraph_node_ptr; |
| 732 | typedef struct cgraph_edge *cgraph_edge_p; | 738 | typedef struct cgraph_edge *cgraph_edge_p; |