]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-92036: Fix gc_fini_untrack() (#92037)
authorVictor Stinner <vstinner@python.org>
Wed, 4 May 2022 09:59:01 +0000 (11:59 +0200)
committerGitHub <noreply@github.com>
Wed, 4 May 2022 09:59:01 +0000 (11:59 +0200)
Fix a crash in subinterpreters related to the garbage collector. When
a subinterpreter is deleted, untrack all objects tracked by its GC.
To prevent a crash in deallocator functions expecting objects to be
tracked by the GC, leak a strong reference to these objects on
purpose, so they are never deleted and their deallocator functions
are not called.

Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst [new file with mode: 0644]
Modules/gcmodule.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst
new file mode 100644 (file)
index 0000000..78094c5
--- /dev/null
@@ -0,0 +1,5 @@
+Fix a crash in subinterpreters related to the garbage collector. When a
+subinterpreter is deleted, untrack all objects tracked by its GC. To prevent a
+crash in deallocator functions expecting objects to be tracked by the GC, leak
+a strong reference to these objects on purpose, so they are never deleted and
+their deallocator functions are not called. Patch by Victor Stinner.
index 802c3eadccfb0c57555a53147eb06dcfcbee9dec..45dad8f0824df85152bf2ebc898e72ccd462a647 100644 (file)
@@ -2165,6 +2165,12 @@ gc_fini_untrack(PyGC_Head *list)
     for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) {
         PyObject *op = FROM_GC(gc);
         _PyObject_GC_UNTRACK(op);
+        // gh-92036: If a deallocator function expect the object to be tracked
+        // by the GC (ex: func_dealloc()), it can crash if called on an object
+        // which is no longer tracked by the GC. Leak one strong reference on
+        // purpose so the object is never deleted and its deallocator is not
+        // called.
+        Py_INCREF(op);
     }
 }