]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 64124] Avoid stack overflows for large command lines
authorPaul Smith <psmith@gnu.org>
Mon, 19 Jun 2023 14:00:11 +0000 (10:00 -0400)
committerPaul Smith <psmith@gnu.org>
Mon, 19 Jun 2023 17:27:50 +0000 (13:27 -0400)
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.

src/function.c
src/main.c
tests/scripts/features/expand

index d4636d7315dd8de4f29ef8a9f598b9aa5ceb7e5d..3b355a33ab9b6254f015afb6d7fb707140efb1a6 100644 (file)
@@ -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;
       }
 
index 39e511ff24c6dead30bbdb84e7c320589b5371fd..1fba1c2108d578915b24ab6e426e231b6ee19cb3 100644 (file)
@@ -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);
 }
 \f
 /* Quote the string IN so that it will be interpreted as a single word with
index 64b9a890cea075139144b2defd0f9e3ba210210e..1d93353091a8ec5dd8279944f21e7e67f2cc6556 100644 (file)
@@ -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) {