bpo-33630: Fix using of freed memory in old versions of glicb for posix_spawn(). (GH-7685)

This commit is contained in:
Pablo Galindo 2018-06-19 09:19:50 +01:00 committed by Serhiy Storchaka
parent b36b0a3765
commit cb970730e3
1 changed files with 22 additions and 3 deletions

View File

@ -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 */