From f154066b61dfde618d98fdafc8cadde076c7f222 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:20:08 -0800 Subject: gcc-plugins/stackleak: Provide verbose mode In order to compare instrumentation between builds, make the verbose mode of the plugin available during the build. This is rarely needed (behind EXPERT) and very noisy (disabled for COMPILE_TEST). Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/Makefile.gcc-plugins | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1d16ca1b78c9..f67153b260c0 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -37,6 +37,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) \ + += -fplugin-arg-stackleak_plugin-verbose ifdef CONFIG_GCC_PLUGIN_STACKLEAK DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable endif -- cgit v1.2.3 From 27e9faf415dbf94af19b9c827842435edbc1fbbc Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:08:20 -0800 Subject: gcc-plugins/stackleak: Exactly match strings instead of prefixes Since STRING_CST may not be NUL terminated, strncmp() was used for check for equality. However, this may lead to mismatches for longer section names where the start matches the tested-for string. Test for exact equality by checking for the presences of NUL termination. Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/gcc-plugins/stackleak_plugin.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index e9db7dcb3e5f..b04aa8e91a41 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -429,6 +429,23 @@ static unsigned int stackleak_cleanup_execute(void) return 0; } +/* + * STRING_CST may or may not be NUL terminated: + * https://gcc.gnu.org/onlinedocs/gccint/Constant-expressions.html + */ +static inline bool string_equal(tree node, const char *string, int length) +{ + if (TREE_STRING_LENGTH(node) < length) + return false; + if (TREE_STRING_LENGTH(node) > length + 1) + return false; + if (TREE_STRING_LENGTH(node) == length + 1 && + TREE_STRING_POINTER(node)[length] != '\0') + return false; + return !memcmp(TREE_STRING_POINTER(node), string, length); +} +#define STRING_EQUAL(node, str) string_equal(node, str, strlen(str)) + static bool stackleak_gate(void) { tree section; @@ -438,13 +455,13 @@ static bool stackleak_gate(void) if (section && TREE_VALUE(section)) { section = TREE_VALUE(TREE_VALUE(section)); - if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10)) + if (STRING_EQUAL(section, ".init.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13)) + if (STRING_EQUAL(section, ".devinit.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13)) + if (STRING_EQUAL(section, ".cpuinit.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13)) + if (STRING_EQUAL(section, ".meminit.text")) return false; } -- cgit v1.2.3 From ae978009fc013e3166c9f523f8b17e41a3c0286e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:12:50 -0800 Subject: gcc-plugins/stackleak: Ignore .noinstr.text and .entry.text The .noinstr.text section functions may not have "current()" sanely available. Similarly true for .entry.text, though such a check is currently redundant. Add a check for both. In an x86_64 defconfig build, the following functions no longer receive stackleak instrumentation: __do_fast_syscall_32() do_int80_syscall_32() do_machine_check() do_syscall_64() exc_general_protection() fixup_bad_iret() Suggested-by: Peter Zijlstra Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/gcc-plugins/stackleak_plugin.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index b04aa8e91a41..42f0252ee2a4 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -463,6 +463,10 @@ static bool stackleak_gate(void) return false; if (STRING_EQUAL(section, ".meminit.text")) return false; + if (STRING_EQUAL(section, ".noinstr.text")) + return false; + if (STRING_EQUAL(section, ".entry.text")) + return false; } return track_frame_size >= 0; -- cgit v1.2.3