From: Pablo Galindo Date: Tue, 19 Jun 2018 08:19:50 +0000 (+0100) Subject: bpo-33630: Fix using of freed memory in old versions of glicb for posix_spawn().... X-Git-Tag: v3.8.0a1~1537 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cb970730e3ca2522e9b1700dcaf0a06b7e898db6;p=python bpo-33630: Fix using of freed memory in old versions of glicb for posix_spawn(). (GH-7685) --- diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 24d8be6666..51fc1c59ca 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5179,7 +5179,8 @@ enum posix_spawn_file_actions_identifier { static int parse_file_actions(PyObject *file_actions, - posix_spawn_file_actions_t *file_actionsp) + posix_spawn_file_actions_t *file_actionsp, + PyObject *temp_buffer) { PyObject *seq; PyObject *file_action = NULL; @@ -5224,9 +5225,13 @@ parse_file_actions(PyObject *file_actions, { goto fail; } + if (PyList_Append(temp_buffer, path)) { + Py_DECREF(path); + goto fail; + } errno = posix_spawn_file_actions_addopen(file_actionsp, fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); - Py_DECREF(path); /* addopen copied it. */ + Py_DECREF(path); if (errno) { posix_error(); goto fail; @@ -5309,6 +5314,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, posix_spawn_file_actions_t *file_actionsp = NULL; Py_ssize_t argc, envc; PyObject *result = NULL; + PyObject *temp_buffer = NULL; pid_t pid; int err_code; @@ -5349,7 +5355,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, } if (file_actions != Py_None) { - if (parse_file_actions(file_actions, &file_actions_buf)) { + /* There is a bug in old versions of glibc that makes some of the + * helper functions for manipulating file actions not copy the provided + * buffers. The problem is that posix_spawn_file_actions_addopen does not + * copy the value of path for some old versions of glibc (<2.20). + * The use of temp_buffer here is a workaround that keeps the + * python objects that own the buffers alive until posix_spawn gets called. + * Check https://bugs.python.org/issue33630 and + * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/ + temp_buffer = PyList_New(0); + if (!temp_buffer) { + goto exit; + } + if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) { goto exit; } file_actionsp = &file_actions_buf; @@ -5376,6 +5394,7 @@ exit: if (argvlist) { free_string_array(argvlist, argc); } + Py_XDECREF(temp_buffer); return result; } #endif /* HAVE_POSIX_SPAWN */