https://github.com/python/cpython/commit/b65c28206fe3e8cc3fbf33b99b563e967986da3d
commit: b65c28206fe3e8cc3fbf33b99b563e967986da3d
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-06-01T14:59:09Z
summary:

[3.15] gh-150157: Fix critical section for PyDict_Next() in _pickle.c 
(GH-150158) (#150711)

(cherry picked from commit c5516e7e371f7b273eb37c7b65f14ef14ee81f11)

Co-authored-by: Thomas Kowalski <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
M 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
index 00000000000000..3a12e26cf736f7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
@@ -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.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 7b87be23269d40..6219706f903159 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -2055,22 +2055,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);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to