mirror of
https://github.com/mirror/make.git
synced 2024-12-26 12:50:20 +08:00
[SV 64124] Avoid stack overflows for large command lines
Modify areas dealing with large command lines to use the heap rather than relying on alloca / stack space. * src/main.c (main): Allocate potentially large buffers with xmalloc. (decode_env_switches): Ditto. * src/function.c (func_error): Replace alloca with xmalloc/free. * tests/scripts/features/expand: Add a newline for readable diffs.
This commit is contained in:
parent
347316fdf6
commit
04f4c2b8d9
@ -1175,11 +1175,12 @@ func_error (char *o, char **argv, const char *funcname)
|
||||
case 'i':
|
||||
{
|
||||
size_t len = strlen (argv[0]);
|
||||
char *msg = alloca (len + 2);
|
||||
char *msg = xmalloc (len + 2);
|
||||
memcpy (msg, argv[0], len);
|
||||
msg[len] = '\n';
|
||||
msg[len + 1] = '\0';
|
||||
outputs (0, msg);
|
||||
free (msg);
|
||||
break;
|
||||
}
|
||||
|
||||
|
14
src/main.c
14
src/main.c
@ -1879,7 +1879,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
/* Now allocate a buffer big enough and fill it. */
|
||||
p = value = alloca (len);
|
||||
p = value = xmalloc (len);
|
||||
for (cv = command_variables; cv != 0; cv = cv->next)
|
||||
{
|
||||
v = cv->variable;
|
||||
@ -1895,6 +1895,7 @@ main (int argc, char **argv, char **envp)
|
||||
/* Define an unchangeable variable with a name that no POSIX.2
|
||||
makefile could validly use for its own variable. */
|
||||
define_variable_cname ("-*-command-variables-*-", value, o_automatic, 0);
|
||||
free (value);
|
||||
|
||||
/* Define the variable; this will not override any user definition.
|
||||
Normally a reference to this variable is written into the value of
|
||||
@ -2041,7 +2042,7 @@ main (int argc, char **argv, char **envp)
|
||||
free (p);
|
||||
}
|
||||
|
||||
p = endp = value = alloca (len);
|
||||
p = endp = value = xmalloc (len);
|
||||
for (i = 0; i < eval_strings->idx; ++i)
|
||||
{
|
||||
p = stpcpy (p, "--eval=");
|
||||
@ -2052,6 +2053,7 @@ main (int argc, char **argv, char **envp)
|
||||
*endp = '\0';
|
||||
|
||||
define_variable_cname ("-*-eval-flags-*-", value, o_automatic, 0);
|
||||
free (value);
|
||||
}
|
||||
|
||||
{
|
||||
@ -3374,8 +3376,8 @@ decode_env_switches (const char *envar, size_t len, enum variable_origin origin)
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
/* Allocate a vector that is definitely big enough. */
|
||||
argv = alloca ((1 + len + 1) * sizeof (char *));
|
||||
/* Allocate an array that is definitely big enough. */
|
||||
argv = xmalloc ((1 + len + 1) * sizeof (char *));
|
||||
|
||||
/* getopt will look at the arguments starting at ARGV[1].
|
||||
Prepend a spacer word. */
|
||||
@ -3384,7 +3386,7 @@ decode_env_switches (const char *envar, size_t len, enum variable_origin origin)
|
||||
|
||||
/* We need a buffer to copy the value into while we split it into words
|
||||
and unquote it. Set up in case we need to prepend a dash later. */
|
||||
buf = alloca (1 + len + 1);
|
||||
buf = xmalloc (1 + len + 1);
|
||||
buf[0] = '-';
|
||||
p = buf+1;
|
||||
argv[argc] = p;
|
||||
@ -3415,6 +3417,8 @@ decode_env_switches (const char *envar, size_t len, enum variable_origin origin)
|
||||
|
||||
/* Parse those words. */
|
||||
decode_switches (argc, argv, origin);
|
||||
free (buf);
|
||||
free (argv);
|
||||
}
|
||||
|
||||
/* Quote the string IN so that it will be interpreted as a single word with
|
||||
|
@ -7,9 +7,9 @@ $description = "Test variable expansion.";
|
||||
# 200 is the initial size of variable_buffer.
|
||||
# Value bigger than 200 bytes causes a realloc of variable_buffer.
|
||||
# In this test the variable being expanded is MAKEFLAGS and its value occupies
|
||||
# 11, 550 and 110000 bytes.
|
||||
# 12, 600 and 120000 bytes.
|
||||
|
||||
my $s = "hello_world";
|
||||
my $s = "hello_world\n";
|
||||
my @mult = (1, 50, 10000);
|
||||
|
||||
for my $m (@mult) {
|
||||
|
Loading…
Reference in New Issue
Block a user