Blame SOURCES/00265-protect-key-list-during-fork.patch

ae2451
diff --git a/Include/pythread.h b/Include/pythread.h
ae2451
index dfd6157..f3e6259 100644
ae2451
--- a/Include/pythread.h
ae2451
+++ b/Include/pythread.h
ae2451
@@ -30,6 +30,8 @@ PyAPI_FUNC(void) PyThread_delete_key(int);
ae2451
 PyAPI_FUNC(int) PyThread_set_key_value(int, void *);
ae2451
 PyAPI_FUNC(void *) PyThread_get_key_value(int);
ae2451
 PyAPI_FUNC(void) PyThread_delete_key_value(int key);
ae2451
+PyAPI_FUNC(int) _PyThread_AcquireKeyLock(void);
ae2451
+PyAPI_FUNC(void) _PyThread_ReleaseKeyLock(void);
ae2451
 
ae2451
 /* Cleanup after a fork */
ae2451
 PyAPI_FUNC(void) PyThread_ReInitTLS(void);
ae2451
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
ae2451
index 022d7aa..8f6cbb2 100644
ae2451
--- a/Modules/posixmodule.c
ae2451
+++ b/Modules/posixmodule.c
ae2451
@@ -65,6 +65,10 @@ corresponding Unix manual entries for more information on calls.");
ae2451
 #include "osdefs.h"
ae2451
 #endif
ae2451
ae2451
+#ifdef WITH_THREAD
ae2451
+#include "pythread.h"
ae2451
+#endif
ae2451
+
ae2451
 #ifdef HAVE_SYS_TYPES_H
ae2451
 #include <sys/types.h>
ae2451
 #endif /* HAVE_SYS_TYPES_H */
ae2451
@@ -3796,7 +3800,18 @@ posix_fork1(PyObject *self, PyObject *noargs)
ae2451
     pid_t pid;
ae2451
     int result = 0;
ae2451
     _PyImport_AcquireLock();
ae2451
+#ifdef WITH_THREAD
ae2451
+    if (_PyThread_AcquireKeyLock() == 0) {
ae2451
+        _PyImport_ReleaseLock();
ae2451
+        PyErr_SetString(PyExc_RuntimeError,
ae2451
+                        "could not acquire thread key lock");
ae2451
+        return NULL;
ae2451
+    }
ae2451
+#endif
ae2451
     pid = fork1();
ae2451
+#ifdef WITH_THREAD
ae2451
+    _PyThread_ReleaseKeyLock();
ae2451
+#endif
ae2451
     if (pid == 0) {
ae2451
         /* child: this clobbers and resets the import lock. */
ae2451
         PyOS_AfterFork();
ae2451
@@ -3829,7 +3844,18 @@ posix_fork(PyObject *self, PyObject *noargs)
ae2451
     pid_t pid;
ae2451
     int result = 0;
ae2451
     _PyImport_AcquireLock();
ae2451
+#ifdef WITH_THREAD
ae2451
+    if (_PyThread_AcquireKeyLock() == 0) {
ae2451
+        _PyImport_ReleaseLock();
ae2451
+        PyErr_SetString(PyExc_RuntimeError,
ae2451
+                        "could not acquire thread key lock");
ae2451
+        return NULL;
ae2451
+    }
ae2451
+#endif
ae2451
     pid = fork();
ae2451
+#ifdef WITH_THREAD
ae2451
+    _PyThread_ReleaseKeyLock();
ae2451
+#endif
ae2451
     if (pid == 0) {
ae2451
         /* child: this clobbers and resets the import lock. */
ae2451
         PyOS_AfterFork();
ae2451
@@ -3955,7 +3981,18 @@ posix_forkpty(PyObject *self, PyObject *noargs)
ae2451
     pid_t pid;
ae2451
 
ae2451
     _PyImport_AcquireLock();
ae2451
+#ifdef WITH_THREAD
ae2451
+    if (_PyThread_AcquireKeyLock() == 0) {
ae2451
+        _PyImport_ReleaseLock();
ae2451
+        PyErr_SetString(PyExc_RuntimeError,
ae2451
+                        "could not acquire thread key lock");
ae2451
+        return NULL;
ae2451
+    }
ae2451
+#endif
ae2451
     pid = forkpty(&master_fd, NULL, NULL, NULL);
ae2451
+#ifdef WITH_THREAD
ae2451
+    _PyThread_ReleaseKeyLock();
ae2451
+#endif
ae2451
     if (pid == 0) {
ae2451
         /* child: this clobbers and resets the import lock. */
ae2451
         PyOS_AfterFork();
ae2451
diff --git a/Python/thread.c b/Python/thread.c
ae2451
index dd333e8..957739e 100644
ae2451
--- a/Python/thread.c
ae2451
+++ b/Python/thread.c
ae2451
@@ -387,6 +387,24 @@ PyThread_delete_key_value(int key)
ae2451
     PyThread_release_lock(keymutex);
ae2451
 }
ae2451
 
ae2451
+int
ae2451
+_PyThread_AcquireKeyLock(void)
ae2451
+{
ae2451
+    if (keymutex == NULL) {
ae2451
+        keymutex = PyThread_allocate_lock();
ae2451
+    }
ae2451
+    if (keymutex == NULL) {
ae2451
+        return 0;
ae2451
+    }
ae2451
+    return PyThread_acquire_lock(keymutex, 1);
ae2451
+}
ae2451
+
ae2451
+void
ae2451
+_PyThread_ReleaseKeyLock(void)
ae2451
+{
ae2451
+    PyThread_release_lock(keymutex);
ae2451
+}
ae2451
+
ae2451
 /* Forget everything not associated with the current thread id.
ae2451
  * This function is called from PyOS_AfterFork().  It is necessary
ae2451
  * because other thread ids which were in use at the time of the fork