[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.
This commit is contained in:
Paul Smith 2023-01-03 02:14:24 -05:00
parent 1ceeb8c64b
commit 5ae02ff8c1
2 changed files with 33 additions and 8 deletions

View file

@ -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 /* These variables are internal to make, and so considered "defined" for the
purposes of warn_undefined even if they are not really defined. */ purposes of warn_undefined even if they are not really defined. */
static const char *const defined_vars[] = { struct defined_vars
"MAKECMDGOALS", "MAKE_RESTARTS", "MAKE_TERMOUT", "MAKE_TERMERR", {
"MAKEOVERRIDES", ".DEFAULT", "-*-command-variables-*-", "-*-eval-flags-*-", const char *name;
"VPATH", "GPATH", size_t len;
NULL }; };
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 void
warn_undefined (const char *name, size_t len) warn_undefined (const char *name, size_t len)
{ {
if (warn_undefined_variables_flag) if (warn_undefined_variables_flag)
{ {
const char *const *cp; const struct defined_vars *dp;
for (cp = defined_vars; *cp != NULL; ++cp) for (dp = defined_vars; dp->name != NULL; ++dp)
if (memcmp (*cp, name, len) == 0 && (*cp)[len] == '\0') if (dp->len == len && memcmp (dp->name, name, len) == 0)
return; return;
error (reading_file, len, _("warning: undefined variable '%.*s'"), error (reading_file, len, _("warning: undefined variable '%.*s'"),

View file

@ -35,4 +35,15 @@ run_make_test(undef, '--warn-undefined-variables',
#MAKEFILE#:9: warning: undefined variable 'UNDEFINED' #MAKEFILE#:9: warning: undefined variable 'UNDEFINED'
ref"); 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; 1;