]> Savannah Git Hosting - gnulib.git/commitdiff
posix_spawn_file_actions_addchdir: Fix possible use-after-free bug.
authorBruno Haible <bruno@clisp.org>
Mon, 10 Jun 2019 14:51:51 +0000 (16:51 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 10 Jun 2019 15:25:03 +0000 (17:25 +0200)
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
* lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make
a copy of the path argument.
* lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
it.

ChangeLog
lib/spawn_faction_addchdir.c
lib/spawn_faction_destroy.c
lib/spawn_int.h

index 16f720d7900b705a7fe081a05a458d6fd211342d..217779ef3dfd3638c9bc52245314a1194b2c056f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2019-06-10  Bruno Haible  <bruno@clisp.org>
+
+       posix_spawn_file_actions_addchdir: Fix possible use-after-free bug.
+       * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
+       * lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make
+       a copy of the path argument.
+       * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
+       it.
+
 2019-06-10  Bruno Haible  <bruno@clisp.org>
 
        posix_spawn_file_actions_addopen: Fix possible use-after-free bug.
index b270e1fca8d01bea4939c3606a6f20c00a5fb302..925874c8cf13dca384e941206830f7c7d24fe824 100644 (file)
@@ -19,6 +19,8 @@
 #include <spawn.h>
 
 #include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 #if REPLACE_POSIX_SPAWN
 # include "spawn_int.h"
@@ -34,24 +36,35 @@ posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions,
 #if !REPLACE_POSIX_SPAWN
   return posix_spawn_file_actions_addchdir_np (file_actions, path);
 #else
-  /* Allocate more memory if needed.  */
-  if (file_actions->_used == file_actions->_allocated
-      && __posix_spawn_file_actions_realloc (file_actions) != 0)
-    /* This can only mean we ran out of memory.  */
-    return ENOMEM;
-
   {
-    struct __spawn_action *rec;
+    /* Copy PATH, because the caller may free it before calling posix_spawn()
+       or posix_spawnp().  */
+    char *path_copy = strdup (path);
+    if (path_copy == NULL)
+      return ENOMEM;
+
+    /* Allocate more memory if needed.  */
+    if (file_actions->_used == file_actions->_allocated
+        && __posix_spawn_file_actions_realloc (file_actions) != 0)
+      {
+        /* This can only mean we ran out of memory.  */
+        free (path_copy);
+        return ENOMEM;
+      }
+
+    {
+      struct __spawn_action *rec;
 
-    /* Add the new value.  */
-    rec = &file_actions->_actions[file_actions->_used];
-    rec->tag = spawn_do_chdir;
-    rec->action.chdir_action.path = path;
+      /* Add the new value.  */
+      rec = &file_actions->_actions[file_actions->_used];
+      rec->tag = spawn_do_chdir;
+      rec->action.chdir_action.path = path_copy;
 
-    /* Account for the new entry.  */
-    ++file_actions->_used;
+      /* Account for the new entry.  */
+      ++file_actions->_used;
 
-    return 0;
+      return 0;
+    }
   }
 #endif
 }
index 0640da483f7fd85be6bf9674bc7be6ef13b41c1e..d7156a0c10fe9ae28765a5056860243737182749 100644 (file)
@@ -42,6 +42,7 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
       switch (sa->tag)
         {
         case spawn_do_open:
+        case spawn_do_chdir:
           free (sa->action.open_action.path);
           break;
         default:
index 08c477a9cbee3182a8627e0428d917a85839c05c..bcf8bbf9fe779a4ecc401572c3fdf190b528d08d 100644 (file)
@@ -48,7 +48,7 @@ struct __spawn_action
     } open_action;
     struct
     {
-      const char *path;
+      char *path;
     } chdir_action;
     struct
     {