summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-05-24 22:27:09 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2022-05-24 22:27:09 +0300
commit0bf13a84362e750a90008af259b098d7c0e0755b (patch)
treef7a315eb2c10ede9d92292a791fcff97486b924c /scripts
parent51518aa68c1ffb54f2fdfed5324af30325529b32 (diff)
parented5edd5a70b9525085403f193786395179ea303d (diff)
downloadlinux-0bf13a84362e750a90008af259b098d7c0e0755b.tar.xz
Merge tag 'kernel-hardening-v5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull kernel hardening updates from Kees Cook: - usercopy hardening expanded to check other allocation types (Matthew Wilcox, Yuanzheng Song) - arm64 stackleak behavioral improvements (Mark Rutland) - arm64 CFI code gen improvement (Sami Tolvanen) - LoadPin LSM block dev API adjustment (Christoph Hellwig) - Clang randstruct support (Bill Wendling, Kees Cook) * tag 'kernel-hardening-v5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (34 commits) loadpin: stop using bdevname mm: usercopy: move the virt_addr_valid() below the is_vmalloc_addr() gcc-plugins: randstruct: Remove cast exception handling af_unix: Silence randstruct GCC plugin warning niu: Silence randstruct warnings big_keys: Use struct for internal payload gcc-plugins: Change all version strings match kernel randomize_kstack: Improve docs on requirements/rationale lkdtm/stackleak: fix CONFIG_GCC_PLUGIN_STACKLEAK=n arm64: entry: use stackleak_erase_on_task_stack() stackleak: add on/off stack variants lkdtm/stackleak: check stack boundaries lkdtm/stackleak: prevent unexpected stack usage lkdtm/stackleak: rework boundary management lkdtm/stackleak: avoid spurious failure stackleak: rework poison scanning stackleak: rework stack high bound handling stackleak: clarify variable names stackleak: rework stack low bound handling stackleak: remove redundant check ...
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.gcc-plugins22
-rw-r--r--scripts/Makefile.randstruct17
-rw-r--r--scripts/basic/.gitignore1
-rw-r--r--scripts/basic/Makefile11
-rw-r--r--scripts/gcc-plugins/Kconfig38
-rw-r--r--scripts/gcc-plugins/Makefile24
-rwxr-xr-xscripts/gcc-plugins/gen-random-seed.sh9
-rw-r--r--scripts/gcc-plugins/latent_entropy_plugin.c2
-rw-r--r--scripts/gcc-plugins/randomize_layout_plugin.c89
-rw-r--r--scripts/gcc-plugins/sancov_plugin.c2
-rw-r--r--scripts/gcc-plugins/stackleak_plugin.c2
-rw-r--r--scripts/gcc-plugins/structleak_plugin.c2
-rwxr-xr-xscripts/gen-randstruct-seed.sh7
13 files changed, 69 insertions, 157 deletions
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index f67153b260c0..692d64a70542 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -8,8 +8,6 @@ ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
endif
export DISABLE_LATENT_ENTROPY_PLUGIN
-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
@@ -24,12 +22,6 @@ export DISABLE_STRUCTLEAK_PLUGIN
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-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+= -DSTACKLEAK_PLUGIN
@@ -53,13 +45,19 @@ export DISABLE_ARM_SSP_PER_TASK_PLUGIN
# All the plugin CFLAGS are collected here in case a build target needs to
# filter them out of the KBUILD_CFLAGS.
GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
-# The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here.
-GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS))
export GCC_PLUGINS_CFLAGS
# Add the flags to the build!
KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
-# All enabled GCC plugins are collected here for building below.
-GCC_PLUGIN := $(gcc-plugin-y)
+# Some plugins are enabled outside of this Makefile, but they still need to
+# be included in GCC_PLUGIN so they can get built.
+gcc-plugin-external-$(CONFIG_GCC_PLUGIN_SANCOV) \
+ += sancov_plugin.so
+gcc-plugin-external-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \
+ += randomize_layout_plugin.so
+
+# All enabled GCC plugins are collected here for building in
+# scripts/gcc-scripts/Makefile.
+GCC_PLUGIN := $(gcc-plugin-y) $(gcc-plugin-external-y)
export GCC_PLUGIN
diff --git a/scripts/Makefile.randstruct b/scripts/Makefile.randstruct
new file mode 100644
index 000000000000..24e283e89893
--- /dev/null
+++ b/scripts/Makefile.randstruct
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+
+randstruct-cflags-y += -DRANDSTRUCT
+
+ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT
+randstruct-cflags-y \
+ += -fplugin=$(objtree)/scripts/gcc-plugins/randomize_layout_plugin.so
+randstruct-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \
+ += -fplugin-arg-randomize_layout_plugin-performance-mode
+else
+randstruct-cflags-y \
+ += -frandomize-layout-seed-file=$(objtree)/scripts/basic/randstruct.seed
+endif
+
+export RANDSTRUCT_CFLAGS := $(randstruct-cflags-y)
+
+KBUILD_CFLAGS += $(RANDSTRUCT_CFLAGS)
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
index 961c91c8a884..07c195f605a1 100644
--- a/scripts/basic/.gitignore
+++ b/scripts/basic/.gitignore
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
/fixdep
+/randstruct.seed
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index eeb6a38c5551..dd289a6725ac 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -3,3 +3,14 @@
# fixdep: used to generate dependency information during build process
hostprogs-always-y += fixdep
+
+# randstruct: the seed is needed before building the gcc-plugin or
+# before running a Clang kernel build.
+gen-randstruct-seed := $(srctree)/scripts/gen-randstruct-seed.sh
+quiet_cmd_create_randstruct_seed = GENSEED $@
+cmd_create_randstruct_seed = \
+ $(CONFIG_SHELL) $(gen-randstruct-seed) \
+ $@ $(objtree)/include/generated/randstruct_hash.h
+$(obj)/randstruct.seed: $(gen-randstruct-seed) FORCE
+ $(call if_changed,create_randstruct_seed)
+always-$(CONFIG_RANDSTRUCT) += randstruct.seed
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index 51d81c3f03d6..e383cda05367 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -46,44 +46,6 @@ config GCC_PLUGIN_LATENT_ENTROPY
* https://grsecurity.net/
* https://pax.grsecurity.net/
-config GCC_PLUGIN_RANDSTRUCT
- bool "Randomize layout of sensitive kernel structures"
- select MODVERSIONS if MODULES
- help
- If you say Y here, the layouts of structures that are entirely
- function pointers (and have not been manually annotated with
- __no_randomize_layout), or structures that have been explicitly
- marked with __randomize_layout, will be randomized at compile-time.
- This can introduce the requirement of an additional information
- exposure vulnerability for exploits targeting these structure
- types.
-
- Enabling this feature will introduce some performance impact,
- slightly increase memory usage, and prevent the use of forensic
- tools like Volatility against the system (unless the kernel
- source tree isn't cleaned after kernel installation).
-
- The seed used for compilation is located at
- scripts/gcc-plugins/randomize_layout_seed.h. It remains after
- a make clean to allow for external modules to be compiled with
- the existing seed and will be removed by a make mrproper or
- make distclean.
-
- This plugin was ported from grsecurity/PaX. More information at:
- * https://grsecurity.net/
- * https://pax.grsecurity.net/
-
-config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
- bool "Use cacheline-aware structure randomization"
- depends on GCC_PLUGIN_RANDSTRUCT
- 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
- groups of elements. It will further not randomize bitfields
- in structures. This reduces the performance hit of RANDSTRUCT
- at the cost of weakened randomization.
-
config GCC_PLUGIN_ARM_SSP_PER_TASK
bool
depends on GCC_PLUGINS && ARM
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 1952d3bb80c6..6f0aecad5d67 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -1,12 +1,17 @@
# SPDX-License-Identifier: GPL-2.0
-$(obj)/randomize_layout_plugin.so: $(objtree)/$(obj)/randomize_layout_seed.h
-quiet_cmd_create_randomize_layout_seed = GENSEED $@
+$(obj)/randomize_layout_plugin.so: $(obj)/randomize_layout_seed.h
+quiet_cmd_create_randomize_layout_seed = SEEDHDR $@
cmd_create_randomize_layout_seed = \
- $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
-$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
+ SEED=$$(cat $(filter-out FORCE,$^) </dev/null); \
+ echo '/*' > $@; \
+ echo ' * This file is automatically generated. Keep it private.' >> $@; \
+ echo ' * Exposing this value will expose the layout of randomized structures.' >> $@; \
+ echo ' */' >> $@; \
+ echo "const char *randstruct_seed = \"$$SEED\";" >> $@
+$(obj)/randomize_layout_seed.h: $(objtree)/scripts/basic/randstruct.seed FORCE
$(call if_changed,create_randomize_layout_seed)
-targets += randomize_layout_seed.h randomize_layout_hash.h
+targets += randomize_layout_seed.h
# Build rules for plugins
#
@@ -23,10 +28,11 @@ GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)
plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
-include $(srctree)/include/linux/compiler-version.h \
- -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \
- -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
- -ggdb -Wno-narrowing -Wno-unused-variable \
- -Wno-format-diag
+ -include $(objtree)/include/generated/utsrelease.h \
+ -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \
+ -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
+ -ggdb -Wno-narrowing -Wno-unused-variable \
+ -Wno-format-diag
plugin_ldflags = -shared
diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh
deleted file mode 100755
index 68af5cc20a64..000000000000
--- a/scripts/gcc-plugins/gen-random-seed.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-if [ ! -f "$1" ]; then
- SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
- echo "const char *randstruct_seed = \"$SEED\";" > "$1"
- HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
- echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
-fi
diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c
index 8425da41de0d..5d415b2572a8 100644
--- a/scripts/gcc-plugins/latent_entropy_plugin.c
+++ b/scripts/gcc-plugins/latent_entropy_plugin.c
@@ -82,7 +82,7 @@ __visible int plugin_is_GPL_compatible;
static GTY(()) tree latent_entropy_decl;
static struct plugin_info latent_entropy_plugin_info = {
- .version = "201606141920vanilla",
+ .version = UTS_RELEASE,
.help = "disable\tturn off latent entropy instrumentation\n",
};
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
index 334741a31d0a..ea2aea570404 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -34,29 +34,11 @@ __visible int plugin_is_GPL_compatible;
static int performance_mode;
static struct plugin_info randomize_layout_plugin_info = {
- .version = "201402201816vanilla",
+ .version = UTS_RELEASE,
.help = "disable\t\t\tdo not activate plugin\n"
"performance-mode\tenable cacheline-aware layout randomization\n"
};
-struct whitelist_entry {
- const char *pathname;
- const char *lhs;
- const char *rhs;
-};
-
-static const struct whitelist_entry whitelist[] = {
- /* NIU overloads mapping with page struct */
- { "drivers/net/ethernet/sun/niu.c", "page", "address_space" },
- /* unix_skb_parms via UNIXCB() buffer */
- { "net/unix/af_unix.c", "unix_skb_parms", "char" },
- /* big_key payload.data struct splashing */
- { "security/keys/big_key.c", "path", "void *" },
- /* walk struct security_hook_heads as an array of struct hlist_head */
- { "security/security.c", "hlist_head", "security_hook_heads" },
- { }
-};
-
/* from old Linux dcache.h */
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
@@ -742,60 +724,6 @@ static void handle_local_var_initializers(void)
}
}
-static bool type_name_eq(gimple stmt, const_tree type_tree, const char *wanted_name)
-{
- const char *type_name;
-
- if (type_tree == NULL_TREE)
- return false;
-
- switch (TREE_CODE(type_tree)) {
- case RECORD_TYPE:
- type_name = TYPE_NAME_POINTER(type_tree);
- break;
- case INTEGER_TYPE:
- if (TYPE_PRECISION(type_tree) == CHAR_TYPE_SIZE)
- type_name = "char";
- else {
- INFORM(gimple_location(stmt), "found non-char INTEGER_TYPE cast comparison: %qT\n", type_tree);
- debug_tree(type_tree);
- return false;
- }
- break;
- case POINTER_TYPE:
- if (TREE_CODE(TREE_TYPE(type_tree)) == VOID_TYPE) {
- type_name = "void *";
- break;
- } else {
- INFORM(gimple_location(stmt), "found non-void POINTER_TYPE cast comparison %qT\n", type_tree);
- debug_tree(type_tree);
- return false;
- }
- default:
- INFORM(gimple_location(stmt), "unhandled cast comparison: %qT\n", type_tree);
- debug_tree(type_tree);
- return false;
- }
-
- return strcmp(type_name, wanted_name) == 0;
-}
-
-static bool whitelisted_cast(gimple stmt, const_tree lhs_tree, const_tree rhs_tree)
-{
- const struct whitelist_entry *entry;
- expanded_location xloc = expand_location(gimple_location(stmt));
-
- for (entry = whitelist; entry->pathname; entry++) {
- if (!strstr(xloc.file, entry->pathname))
- continue;
-
- if (type_name_eq(stmt, lhs_tree, entry->lhs) && type_name_eq(stmt, rhs_tree, entry->rhs))
- return true;
- }
-
- return false;
-}
-
/*
* iterate over all statements to find "bad" casts:
* those where the address of the start of a structure is cast
@@ -872,10 +800,7 @@ static unsigned int find_bad_casts_execute(void)
#ifndef __DEBUG_PLUGIN
if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_lhs_type)))
#endif
- {
- if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
- MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type);
- }
+ MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type);
continue;
}
@@ -898,10 +823,7 @@ static unsigned int find_bad_casts_execute(void)
#ifndef __DEBUG_PLUGIN
if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(op0_type)))
#endif
- {
- if (!whitelisted_cast(stmt, ptr_lhs_type, op0_type))
- MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type);
- }
+ MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type);
} else {
const_tree ssa_name_var = SSA_NAME_VAR(rhs1);
/* skip bogus type casts introduced by container_of */
@@ -911,10 +833,7 @@ static unsigned int find_bad_casts_execute(void)
#ifndef __DEBUG_PLUGIN
if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_rhs_type)))
#endif
- {
- if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
- MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type);
- }
+ MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type);
}
}
diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c
index 23bd023a283b..f3d629555b84 100644
--- a/scripts/gcc-plugins/sancov_plugin.c
+++ b/scripts/gcc-plugins/sancov_plugin.c
@@ -26,7 +26,7 @@ __visible int plugin_is_GPL_compatible;
tree sancov_fndecl;
static struct plugin_info sancov_plugin_info = {
- .version = "20160402",
+ .version = UTS_RELEASE,
.help = "sancov plugin\n",
};
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
index 42f0252ee2a4..de817d54b8af 100644
--- a/scripts/gcc-plugins/stackleak_plugin.c
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -44,7 +44,7 @@ static bool verbose = false;
static GTY(()) tree track_function_decl;
static struct plugin_info stackleak_plugin_info = {
- .version = "201707101337",
+ .version = UTS_RELEASE,
.help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n"
"arch=target_arch\tspecify target build arch\n"
"disable\t\tdo not activate the plugin\n"
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index 74e319288389..86b608a24ec0 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -37,7 +37,7 @@
__visible int plugin_is_GPL_compatible;
static struct plugin_info structleak_plugin_info = {
- .version = "20190125vanilla",
+ .version = UTS_RELEASE,
.help = "disable\tdo not activate plugin\n"
"byref\tinit structs passed by reference\n"
"byref-all\tinit anything passed by reference\n"
diff --git a/scripts/gen-randstruct-seed.sh b/scripts/gen-randstruct-seed.sh
new file mode 100755
index 000000000000..61017b36c464
--- /dev/null
+++ b/scripts/gen-randstruct-seed.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+SEED=$(od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n')
+echo "$SEED" > "$1"
+HASH=$(echo -n "$SEED" | sha256sum | cut -d" " -f1)
+echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"