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
This commit is contained in:
Eric Snow 2018-09-14 14:17:20 -07:00 committed by GitHub
parent 3faaa8857a
commit 5903296045
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 14 deletions

View file

@ -268,6 +268,44 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
}
/*
* Delete all interpreter states except the main interpreter. If there
* is a current interpreter state, it *must* be the main interpreter.
*/
void
_PyInterpreterState_DeleteExceptMain()
{
PyThreadState *tstate = PyThreadState_Swap(NULL);
if (tstate != NULL && tstate->interp != _PyRuntime.interpreters.main) {
Py_FatalError("PyInterpreterState_DeleteExceptMain: not main interpreter");
}
HEAD_LOCK();
PyInterpreterState *interp = _PyRuntime.interpreters.head;
_PyRuntime.interpreters.head = NULL;
for (; interp != NULL; interp = interp->next) {
if (interp == _PyRuntime.interpreters.main) {
_PyRuntime.interpreters.main->next = NULL;
_PyRuntime.interpreters.head = interp;
continue;
}
PyInterpreterState_Clear(interp); // XXX must activate?
zapthreads(interp);
if (interp->id_mutex != NULL) {
PyThread_free_lock(interp->id_mutex);
}
PyMem_RawFree(interp);
}
HEAD_UNLOCK();
if (_PyRuntime.interpreters.head == NULL) {
Py_FatalError("PyInterpreterState_DeleteExceptMain: missing main");
}
PyThreadState_Swap(tstate);
}
PyInterpreterState *
_PyInterpreterState_Get(void)
{