@@ -5179,7 +5179,8 @@ enum posix_spawn_file_actions_identifier {
51795179
51805180static int
51815181parse_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