+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.
#include <spawn.h>
#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
#if REPLACE_POSIX_SPAWN
# include "spawn_int.h"
#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
}