mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
313dd1b629
This randstruct plugin is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. The randstruct GCC plugin randomizes the layout of selected structures at compile time, as a probabilistic defense against attacks that need to know the layout of structures within the kernel. This is most useful for "in-house" kernel builds where neither the randomization seed nor other build artifacts are made available to an attacker. While less useful for distribution kernels (where the randomization seed must be exposed for third party kernel module builds), it still has some value there since now all kernel builds would need to be tracked by an attacker. In more performance sensitive scenarios, GCC_PLUGIN_RANDSTRUCT_PERFORMANCE can be selected to make a best effort to restrict randomization to cacheline-sized groups of elements, and will not randomize bitfields. This comes at the cost of reduced randomization. Two annotations are defined,__randomize_layout and __no_randomize_layout, which respectively tell the plugin to either randomize or not to randomize instances of the struct in question. Follow-on patches enable the auto-detection logic for selecting structures for randomization that contain only function pointers. It is disabled here to assist with bisection. Since any randomized structs must be initialized using designated initializers, __randomize_layout includes the __designated_init annotation even when the plugin is disabled so that all builds will require the needed initialization. (With the plugin enabled, annotations for automatically chosen structures are marked as well.) The main differences between this implemenation and grsecurity are: - disable automatic struct selection (to be enabled in follow-up patch) - add designated_init attribute at runtime and for manual marking - clarify debugging output to differentiate bad cast warnings - add whitelisting infrastructure - support gcc 7's DECL_ALIGN and DECL_MODE changes (Laura Abbott) - raise minimum required GCC version to 4.7 Earlier versions of this patch series were ported by Michael Leibowitz. Signed-off-by: Kees Cook <keescook@chromium.org>
84 lines
3.4 KiB
Makefile
84 lines
3.4 KiB
Makefile
ifdef CONFIG_GCC_PLUGINS
|
|
__PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
|
|
PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
|
|
|
|
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
|
|
DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
|
|
endif
|
|
|
|
ifdef CONFIG_GCC_PLUGIN_SANCOV
|
|
ifeq ($(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) += -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
|
|
@:
|
|
|
|
# Actually do the build, if requested.
|
|
PHONY += gcc-plugins
|
|
gcc-plugins: scripts_basic gcc-plugins-check
|
|
ifdef CONFIG_GCC_PLUGINS
|
|
$(Q)$(MAKE) $(build)=scripts/gcc-plugins
|
|
endif
|
|
@:
|