diff options
author | Paul Smith <psmith@gnu.org> | 2023-01-03 02:14:24 -0500 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2023-01-03 02:14:24 -0500 |
commit | 5ae02ff8c10e611aca7d5c6f60d3461aa0746694 (patch) | |
tree | d303732dc24ff23150a400172cbfb132e31afba3 | |
parent | 1ceeb8c64bf2a95bdfc5e5bd221886c6df74f560 (diff) | |
download | make-git-5ae02ff8c10e611aca7d5c6f60d3461aa0746694.tar.gz |
[SV 63609] Avoid buffer overrun in --warn-undefined-variables
Reported by Dmitry Goncharov <dgoncharov@users.sf.net>
* src/variable.c (struct defined_vars): Create a struct that holds the
name and length of each variable name.
(warn_undefined): Check the lengths before comparing the contents.
* tests/scripts/options/warn-undefined-variables: Add a test.
-rw-r--r-- | src/variable.c | 30 | ||||
-rw-r--r-- | tests/scripts/options/warn-undefined-variables | 11 |
2 files changed, 33 insertions, 8 deletions
diff --git a/src/variable.c b/src/variable.c index a0299639..009ee540 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1793,20 +1793,34 @@ try_variable_definition (const floc *flocp, const char *line, /* These variables are internal to make, and so considered "defined" for the purposes of warn_undefined even if they are not really defined. */ -static const char *const defined_vars[] = { - "MAKECMDGOALS", "MAKE_RESTARTS", "MAKE_TERMOUT", "MAKE_TERMERR", - "MAKEOVERRIDES", ".DEFAULT", "-*-command-variables-*-", "-*-eval-flags-*-", - "VPATH", "GPATH", - NULL }; +struct defined_vars + { + const char *name; + size_t len; + }; + +static const struct defined_vars defined_vars[] = { + { STRING_SIZE_TUPLE ("MAKECMDGOALS") }, + { STRING_SIZE_TUPLE ("MAKE_RESTARTS") }, + { STRING_SIZE_TUPLE ("MAKE_TERMOUT") }, + { STRING_SIZE_TUPLE ("MAKE_TERMERR") }, + { STRING_SIZE_TUPLE ("MAKEOVERRIDES") }, + { STRING_SIZE_TUPLE (".DEFAULT") }, + { STRING_SIZE_TUPLE ("-*-command-variables-*-") }, + { STRING_SIZE_TUPLE ("-*-eval-flags-*-") }, + { STRING_SIZE_TUPLE ("VPATH") }, + { STRING_SIZE_TUPLE ("GPATH") }, + { NULL, 0 } +}; void warn_undefined (const char *name, size_t len) { if (warn_undefined_variables_flag) { - const char *const *cp; - for (cp = defined_vars; *cp != NULL; ++cp) - if (memcmp (*cp, name, len) == 0 && (*cp)[len] == '\0') + const struct defined_vars *dp; + for (dp = defined_vars; dp->name != NULL; ++dp) + if (dp->len == len && memcmp (dp->name, name, len) == 0) return; error (reading_file, len, _("warning: undefined variable '%.*s'"), diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables index 9bd40865..d9653d2c 100644 --- a/tests/scripts/options/warn-undefined-variables +++ b/tests/scripts/options/warn-undefined-variables @@ -35,4 +35,15 @@ run_make_test(undef, '--warn-undefined-variables', #MAKEFILE#:9: warning: undefined variable 'UNDEFINED' ref"); +# sv 63609. +# Test for buffer overrun in warn_undefined. +run_make_test(q! +all:; +X := $(averyveryverylongvariablename) +!, + '--warn-undefined-variables', + "#MAKEFILE#:3: warning: undefined variable 'averyveryverylongvariablename' +#MAKE#: 'all' is up to date.\n" +); + 1; |