https://github.com/python/cpython/commit/6f9525dd3f0ef5809106ca0923a7512d666a04bb
commit: 6f9525dd3f0ef5809106ca0923a7512d666a04bb
branch: main
author: Neil Schemenauer <nas-git...@arctrix.com>
committer: nascheme <nas-git...@arctrix.com>
date: 2024-09-26T19:33:07-07:00
summary:

gh-116510: Fix crash during sub-interpreter shutdown (gh-124645)

Fix a bug that can cause a crash when sub-interpreters use "basic"
single-phase extension modules.  Shared objects could refer to PyGC_Head
nodes that had been freed as part of interpreter shutdown.

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst
M Python/gc.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst
new file mode 100644
index 00000000000000..fc3f8af72d87bf
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst
@@ -0,0 +1,3 @@
+Fix a bug that can cause a crash when sub-interpreters use "basic"
+single-phase extension modules.  Shared objects could refer to PyGC_Head
+nodes that had been freed as part of interpreter cleanup.
diff --git a/Python/gc.c b/Python/gc.c
index 024d041437be4a..028657eb8999c1 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1944,6 +1944,13 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
     }
 }
 
+static void
+finalize_unlink_gc_head(PyGC_Head *gc) {
+    PyGC_Head *prev = GC_PREV(gc);
+    PyGC_Head *next = GC_NEXT(gc);
+    _PyGCHead_SET_NEXT(prev, next);
+    _PyGCHead_SET_PREV(next, prev);
+}
 
 void
 _PyGC_Fini(PyInterpreterState *interp)
@@ -1952,9 +1959,25 @@ _PyGC_Fini(PyInterpreterState *interp)
     Py_CLEAR(gcstate->garbage);
     Py_CLEAR(gcstate->callbacks);
 
-    /* We expect that none of this interpreters objects are shared
-       with other interpreters.
-       See https://github.com/python/cpython/issues/90228. */
+    /* Prevent a subtle bug that affects sub-interpreters that use basic
+     * single-phase init extensions (m_size == -1).  Those extensions cause 
objects
+     * to be shared between interpreters, via the PyDict_Update(mdict, m_copy) 
call
+     * in import_find_extension().
+     *
+     * If they are GC objects, their GC head next or prev links could refer to
+     * the interpreter _gc_runtime_state PyGC_Head nodes.  Those nodes go away
+     * when the interpreter structure is freed and so pointers to them become
+     * invalid.  If those objects are still used by another interpreter and
+     * UNTRACK is called on them, a crash will happen.  We untrack the nodes
+     * here to avoid that.
+     *
+     * This bug was originally fixed when reported as gh-90228.  The bug was
+     * re-introduced in gh-94673.
+     */
+    finalize_unlink_gc_head(&gcstate->young.head);
+    finalize_unlink_gc_head(&gcstate->old[0].head);
+    finalize_unlink_gc_head(&gcstate->old[1].head);
+    finalize_unlink_gc_head(&gcstate->permanent_generation.head);
 }
 
 /* for debugging */

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to