diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2018-09-14 21:17:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-14 21:17:20 (GMT) |
commit | 5903296045b586b9cd1fce0b1e02caf896028d1d (patch) | |
tree | 99e8900633096060e931980d52e063c044870d3c /Modules | |
parent | 3faaa8857a42a36383bb18425444e597fc876797 (diff) | |
download | cpython-5903296045b586b9cd1fce0b1e02caf896028d1d.zip cpython-5903296045b586b9cd1fce0b1e02caf896028d1d.tar.gz cpython-5903296045b586b9cd1fce0b1e02caf896028d1d.tar.bz2 |
bpo-34651: Only allow the main interpreter to fork. (gh-9279)
When os.fork() is called (on platforms that support it) all threads but the current one are destroyed in the child process. Consequently we must ensure that all but the associated interpreter are likewise destroyed. The main interpreter is critical for runtime operation, so we must ensure that fork only happens in the main interpreter.
https://bugs.python.org/issue34651
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_posixsubprocess.c | 5 | ||||
-rw-r--r-- | Modules/posixmodule.c | 14 |
2 files changed, 19 insertions, 0 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index dd69b9e..9661e38 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -576,6 +576,11 @@ subprocess_fork_exec(PyObject* self, PyObject *args) &restore_signals, &call_setsid, &preexec_fn)) return NULL; + if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; + } + if (close_fds && errpipe_write < 3) { /* precondition */ PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); return NULL; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2fddd95..0ac0042 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -32,6 +32,7 @@ #else #include "winreparse.h" #endif +#include "internal/pystate.h" /* On android API level 21, 'AT_EACCESS' is not declared although * HAVE_FACCESSAT is defined. */ @@ -420,6 +421,7 @@ void PyOS_AfterFork_Child(void) { _PyGILState_Reinit(); + _PyInterpreterState_DeleteExceptMain(); PyEval_ReInitThreads(); _PyImport_ReInitLock(); _PySignal_AfterFork(); @@ -5790,6 +5792,10 @@ os_fork1_impl(PyObject *module) { pid_t pid; + if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; + } PyOS_BeforeFork(); pid = fork1(); if (pid == 0) { @@ -5821,6 +5827,10 @@ os_fork_impl(PyObject *module) { pid_t pid; + if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; + } PyOS_BeforeFork(); pid = fork(); if (pid == 0) { @@ -6416,6 +6426,10 @@ os_forkpty_impl(PyObject *module) int master_fd = -1; pid_t pid; + if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; + } PyOS_BeforeFork(); pid = forkpty(&master_fd, NULL, NULL, NULL); if (pid == 0) { |