]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-150157: Fix critical section for PyDict_Next() in _pickle.c (GH-150158...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 1 Jun 2026 14:57:52 +0000 (16:57 +0200)
committerGitHub <noreply@github.com>
Mon, 1 Jun 2026 14:57:52 +0000 (14:57 +0000)
(cherry picked from commit c5516e7e371f7b273eb37c7b65f14ef14ee81f11)

Co-authored-by: Thomas Kowalski <thom.kowa@gmail.com>
Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst [new file with mode: 0644]
Modules/_pickle.c

diff --git a/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst b/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
new file mode 100644 (file)
index 0000000..3a12e26
--- /dev/null
@@ -0,0 +1,3 @@
+Fix a crash in free-threaded builds that occurs when pickling by name
+objects without a ``__module__`` attribute while :data:`sys.modules`
+is concurrently being modified.
index 75e1c4dea85e0041a0b43b7cd2f2c341da58aca4..9a6f24ec86496308309b59834c6fcf46f89b79b6 100644 (file)
@@ -1947,22 +1947,34 @@ whichmodule(PickleState *st, PyObject *global, PyObject *global_name, PyObject *
             return NULL;
         }
         if (PyDict_CheckExact(modules)) {
+            PyObject *found_name = NULL;
+            int error = 0;
             i = 0;
+            Py_BEGIN_CRITICAL_SECTION(modules);
             while (PyDict_Next(modules, &i, &module_name, &module)) {
                 Py_INCREF(module_name);
                 Py_INCREF(module);
                 if (_checkmodule(module_name, module, global, dotted_path) == 0) {
                     Py_DECREF(module);
-                    Py_DECREF(modules);
-                    return module_name;
+                    found_name = module_name;
+                    break;
                 }
                 Py_DECREF(module);
                 Py_DECREF(module_name);
                 if (PyErr_Occurred()) {
-                    Py_DECREF(modules);
-                    return NULL;
+                    error = 1;
+                    break;
                 }
             }
+            Py_END_CRITICAL_SECTION();
+            if (error) {
+                Py_DECREF(modules);
+                return NULL;
+            }
+            if (found_name != NULL) {
+                Py_DECREF(modules);
+                return found_name;
+            }
         }
         else {
             PyObject *iterator = PyObject_GetIter(modules);