]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Fix issues found by ASAN and Coverity
authorPaul Smith <psmith@gnu.org>
Mon, 31 Oct 2022 05:48:33 +0000 (01:48 -0400)
committerPaul Smith <psmith@gnu.org>
Mon, 31 Oct 2022 06:23:04 +0000 (02:23 -0400)
* tests/test_driver.pl: Preserve the LSAN_OPTIONS variable.
* tests/scripts/targets/ONESHELL: Don't set a local variable.
* tests/scripts/functions/let: Test empty let variable.
* src/posixos.c (osync_parse_mutex): Free existing osync_tmpfile.
* src/misc.c (get_tmpfd): Set umask() before invoking mkstemp().
* src/ar.c (ar_parse_name): Check invalid name (shouldn't happen).
* src/function.c (define_new_function): Free previous function entry
when replacing it with a new one.
* src/job.c (child_execute_job): Initialize pid for safety.
(construct_command_argv_internal): In oneshell mode ensure that the
returned argv has the right format (0th element is a pointer to the
entire buffer).

src/ar.c
src/dir.c
src/function.c
src/job.c
src/misc.c
src/posixos.c
tests/scripts/features/varnesting
tests/scripts/functions/let
tests/scripts/targets/ONESHELL
tests/test_driver.pl

index 8b02f047c1527f033499c6adbf7da4d086cb979f..7b607dcdf570689cb87c718bb16b286baae39f71 100644 (file)
--- a/src/ar.c
+++ b/src/ar.c
@@ -36,7 +36,7 @@ ar_name (const char *name)
   const char *p = strchr (name, '(');
   const char *end;
 
-  if (p == 0 || p == name)
+  if (p == NULL || p == name)
     return 0;
 
   end = p + strlen (p) - 1;
@@ -61,6 +61,9 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
 
   *arname_p = xstrdup (name);
   p = strchr (*arname_p, '(');
+  /* This is never called unless ar_name() is true so p cannot be NULL.  */
+  if (!p)
+    OS (fatal, NILF, "Internal: ar_parse_name: bad name '%s'", *arname_p);
   *(p++) = '\0';
   p[strlen (p) - 1] = '\0';
   *memname_p = p;
index 3577a12ddec26ae74ad19029ccf64532f9986ea3..b47e94fed3d369b9a021496bdeb94f4a4c35211c 100644 (file)
--- a/src/dir.c
+++ b/src/dir.c
@@ -601,7 +601,7 @@ find_directory (const char *name)
   /* Point the name-hashed entry for DIR at its contents data.  */
   dir->contents = dc;
 
-  /* If the contents have changed, we need to reseet.  */
+  /* If the contents have changed, we need to reseed.  */
   if (dc->counter != command_count)
     {
       if (dc->counter)
index db5e1b51cc16049f8b1ddcbcf75ff9e21aaab512..f0ef34348d6141a3a97691467a74090845d7f6a0 100644 (file)
@@ -2811,7 +2811,8 @@ define_new_function (const floc *flocp, const char *name,
   ent->adds_command = 1;
   ent->fptr.alloc_func_ptr = func;
 
-  hash_insert (&function_table, ent);
+  ent = hash_insert (&function_table, ent);
+  free (ent);
 }
 
 void
index ed951026ee6ce9a353a00b095f70ee7e04aa11d2..b78f279c5a72748009dac3ac2a4a19ae18116855 100644 (file)
--- a/src/job.c
+++ b/src/job.c
@@ -2271,7 +2271,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
   const int fdin = good_stdin ? FD_STDIN : get_bad_stdin ();
   int fdout = FD_STDOUT;
   int fderr = FD_STDERR;
-  pid_t pid;
+  pid_t pid = -1;
   int r;
 #if defined(USE_POSIX_SPAWN)
   char *cmd;
@@ -3364,30 +3364,44 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 #endif /* WINDOWS32 */
         /* Create an argv list for the shell command line.  */
         {
-          int n = 0;
+          int n = 1;
+          char *nextp;
 
           new_argv = xmalloc ((4 + sflags_len/2) * sizeof (char *));
-          new_argv[n++] = xstrdup (shell);
+
+          nextp = new_argv[0] = xmalloc (shell_len + sflags_len + line_len + 3);
+          nextp = mempcpy (nextp, shell, shell_len + 1);
 
           /* Chop up the shellflags (if any) and assign them.  */
           if (! shellflags)
-            new_argv[n++] = xstrdup ("");
+            {
+              new_argv[n++] = nextp;
+              *(nextp++) = '\0';
+            }
           else
             {
               /* Parse shellflags using construct_command_argv_internal to
                  handle quotes. */
-              char **argv, **a;
-              char *f;
-              f = alloca (sflags_len + 1); /* +1 for null terminator.  */
+              char **argv;
+              char *f = alloca (sflags_len + 1);
               memcpy (f, shellflags, sflags_len + 1);
               argv = construct_command_argv_internal (f, 0, 0, 0, 0, flags, 0);
-              for (a = argv; a && *a; ++a)
-                new_argv[n++] = *a;
-              free (argv);
+              if (argv)
+                {
+                  char **a;
+                  for (a = argv; *a; ++a)
+                    {
+                      new_argv[n++] = nextp;
+                      nextp = stpcpy (nextp, *a) + 1;
+                    }
+                  free (argv[0]);
+                  free (argv);
+                }
             }
 
           /* Set the command to invoke.  */
-          new_argv[n++] = line;
+          new_argv[n++] = nextp;
+          memcpy(nextp, line, line_len + 1);
           new_argv[n++] = NULL;
         }
         return new_argv;
index bf6fe7caefc1183f77e6b16513a3f4fcbd49dcd1..8264fe9f7a2a0a1a413fba7a9a1072a7fbb0062a 100644 (file)
@@ -668,6 +668,7 @@ get_tmpfd (char **name)
 {
   int fd = -1;
   char *tmpnm;
+  mode_t mask;
 
   /* If there's an os-specific way to get an anoymous temp file use it.  */
   if (!name)
@@ -677,6 +678,10 @@ get_tmpfd (char **name)
         return fd;
     }
 
+  /* Preserve the current umask, and set a restrictive one for temp files.
+     Only really needed for mkstemp() but won't hurt for the open method.  */
+  mask = umask (0077);
+
 #if defined(HAVE_MKSTEMP)
   tmpnm = get_tmptemplate ();
 
@@ -704,6 +709,8 @@ get_tmpfd (char **name)
       free (tmpnm);
     }
 
+  umask (mask);
+
   return fd;
 }
 
index 63201b400403cd996dd7b43a698cf57f87a9c244..44aeb3464b4ee5c25373c62ce3c0b7835c93a124 100644 (file)
@@ -673,6 +673,7 @@ osync_parse_mutex (const char *mutex)
       return 0;
     }
 
+  free (osync_tmpfile);
   osync_tmpfile = xstrdup (mutex + CSTRLEN (MUTEX_PREFIX));
 
   EINTRLOOP (osync_handle, open (osync_tmpfile, O_WRONLY));
index d8f3ffbb12b1907711b77c6a005e81cd34064b90..0fbb332d61884f0b36a6a5e3e897f2af1fc067fc 100644 (file)
@@ -9,8 +9,7 @@ variable2 := Hello
 y = $(subst 1,2,$(x))
 z = y
 a := $($($(z)))
-all: 
-       @echo $(a)
+all: ; @echo $(a)
 ',
               '', "Hello\n");
 
@@ -21,15 +20,8 @@ all:
 
 run_make_test('
 VARIABLE = $(eval VARIABLE := echo hi)$(VARIABLE)
-wololo:
-       @$(VARIABLE)
+wololo: ; @$(VARIABLE)
 ',
               '', "hi\n");
 
 1;
-
-
-
-
-
-
index f1012e56ce198dd25fde558796016609dc24c15a..48aec78fa3af9c41b0e76e62aa2164ac89d9a462 100644 (file)
@@ -39,11 +39,12 @@ all:;@echo 'a=,$a,' 'b=,$b,' 'x=,$x,' 'y=,$y,' 'z=,$z,'
 # We still expand the list and body.
 run_make_test('
 null =
+v = $(let    ,$(info blankvar),abc)
 x = $(let $(null),$(info side-effect),abc)
 y = $(let y,,$ydef)
 
-all: ; @echo $x$y',
-              '', "side-effect\nabcdef\n");
+all: ; @echo $v/$x/$y',
+              '', "blankvar\nside-effect\nabc/abc/def\n");
 
 # The example macro from the manual.
 run_make_test('
index 481de088eda6062a9c9dd182674ec10b5bee3e2c..f9da14b31885a230eb605b62cf399521dab0c1d1 100644 (file)
@@ -10,7 +10,7 @@ if ($port_type ne 'W32') {
     # Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
     # separate arguments.
     my $t = `$sh_name -e -c true 2>/dev/null`;
-    my $multi_ok = $? == 0;
+    $multi_ok = $? == 0;
 }
 
 # Simple
index 58a782f66a13ed6ad7859cce86b56f80ee74f8d1..b64fffb64ece3ab38772e64dc3fa19d7cbc2ba92 100644 (file)
@@ -197,7 +197,7 @@ sub toplevel
            'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
            'LD_LIBRARY_PATH',
            # *SAN things
-           'ASAN_OPTIONS', 'UBSAN_OPTIONS',
+           'ASAN_OPTIONS', 'UBSAN_OPTIONS', 'LSAN_OPTIONS',
            # Purify things
            'PURIFYOPTIONS',
            # Windows-specific things