Skip to content

Commit cb97073

Browse files
pablogsalserhiy-storchaka
authored andcommitted
bpo-33630: Fix using of freed memory in old versions of glicb for posix_spawn(). (GH-7685)
1 parent b36b0a3 commit cb97073

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

Modules/posixmodule.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5179,7 +5179,8 @@ enum posix_spawn_file_actions_identifier {
51795179

51805180
static int
51815181
parse_file_actions(PyObject *file_actions,
5182-
posix_spawn_file_actions_t *file_actionsp)
5182+
posix_spawn_file_actions_t *file_actionsp,
5183+
PyObject *temp_buffer)
51835184
{
51845185
PyObject *seq;
51855186
PyObject *file_action = NULL;
@@ -5224,9 +5225,13 @@ parse_file_actions(PyObject *file_actions,
52245225
{
52255226
goto fail;
52265227
}
5228+
if (PyList_Append(temp_buffer, path)) {
5229+
Py_DECREF(path);
5230+
goto fail;
5231+
}
52275232
errno = posix_spawn_file_actions_addopen(file_actionsp,
52285233
fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
5229-
Py_DECREF(path); /* addopen copied it. */
5234+
Py_DECREF(path);
52305235
if (errno) {
52315236
posix_error();
52325237
goto fail;
@@ -5309,6 +5314,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
53095314
posix_spawn_file_actions_t *file_actionsp = NULL;
53105315
Py_ssize_t argc, envc;
53115316
PyObject *result = NULL;
5317+
PyObject *temp_buffer = NULL;
53125318
pid_t pid;
53135319
int err_code;
53145320

@@ -5349,7 +5355,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
53495355
}
53505356

53515357
if (file_actions != Py_None) {
5352-
if (parse_file_actions(file_actions, &file_actions_buf)) {
5358+
/* There is a bug in old versions of glibc that makes some of the
5359+
* helper functions for manipulating file actions not copy the provided
5360+
* buffers. The problem is that posix_spawn_file_actions_addopen does not
5361+
* copy the value of path for some old versions of glibc (<2.20).
5362+
* The use of temp_buffer here is a workaround that keeps the
5363+
* python objects that own the buffers alive until posix_spawn gets called.
5364+
* Check https://bugs.python.org/issue33630 and
5365+
* https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5366+
temp_buffer = PyList_New(0);
5367+
if (!temp_buffer) {
5368+
goto exit;
5369+
}
5370+
if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
53535371
goto exit;
53545372
}
53555373
file_actionsp = &file_actions_buf;
@@ -5376,6 +5394,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
53765394
if (argvlist) {
53775395
free_string_array(argvlist, argc);
53785396
}
5397+
Py_XDECREF(temp_buffer);
53795398
return result;
53805399
}
53815400
#endif /* HAVE_POSIX_SPAWN */

0 commit comments

Comments
 (0)