>From b827d8a6fab0c25eaf0c59b94c5bbef00efeeae5 Mon Sep 17 00:00:00 2001
From: Bruno Haible
Date: Mon, 10 Jun 2019 16:51:51 +0200
Subject: [PATCH 5/5] 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.
---
ChangeLog | 9 +++++++++
lib/spawn_faction_addchdir.c | 41 +++++++++++++++++++++++++++--------------
lib/spawn_faction_destroy.c | 1 +
lib/spawn_int.h | 2 +-
4 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 16f720d..217779e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2019-06-10 Bruno Haible
+ 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
+
posix_spawn_file_actions_addopen: Fix possible use-after-free bug.
Reported at .
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
diff --git a/lib/spawn_faction_addchdir.c b/lib/spawn_faction_addchdir.c
index b270e1f..925874c 100644
--- a/lib/spawn_faction_addchdir.c
+++ b/lib/spawn_faction_addchdir.c
@@ -19,6 +19,8 @@
#include
#include
+#include
+#include
#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
}
diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c
index 0640da4..d7156a0 100644
--- a/lib/spawn_faction_destroy.c
+++ b/lib/spawn_faction_destroy.c
@@ -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:
diff --git a/lib/spawn_int.h b/lib/spawn_int.h
index 08c477a..bcf8bbf 100644
--- a/lib/spawn_int.h
+++ b/lib/spawn_int.h
@@ -48,7 +48,7 @@ struct __spawn_action
} open_action;
struct
{
- const char *path;
+ char *path;
} chdir_action;
struct
{
--
2.7.4