>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