gcc-plugins/stackleak: Exactly match strings instead of prefixes
authorKees Cook <keescook@chromium.org>
Sun, 6 Feb 2022 17:08:20 +0000 (09:08 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:23:54 +0000 (14:23 +0200)
[ Upstream commit 27e9faf415dbf94af19b9c827842435edbc1fbbc ]

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 <alex.popov@linux.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
scripts/gcc-plugins/stackleak_plugin.c

index e9db7dc..b04aa8e 100644 (file)
@@ -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;
        }