]> granicus.if.org Git - python/commitdiff
bpo-33630: Fix using of freed memory in old versions of glicb for posix_spawn()....
authorPablo Galindo <Pablogsal@gmail.com>
Tue, 19 Jun 2018 08:19:50 +0000 (09:19 +0100)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 19 Jun 2018 08:19:50 +0000 (11:19 +0300)
Modules/posixmodule.c

index 24d8be66665e82e7f0d0f4e1f96463307cfadaaf..51fc1c59ca84784402c52c47f0a8b31685163239 100644 (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 */