[Python-checkins] bpo-44184: Apply GH-26274 to the non-GC-type branch of subtype_dealloc (GH-27165) (GH-27174)

Yhg1s webhook-mailer at python.org
Thu Jul 15 19:18:42 EDT 2021


https://github.com/python/cpython/commit/6aa59c68dc7910c0675ad23c1f9d88edfb81dfcb
commit: 6aa59c68dc7910c0675ad23c1f9d88edfb81dfcb
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Yhg1s <thomas at python.org>
date: 2021-07-16T01:18:16+02:00
summary:

bpo-44184: Apply GH-26274 to the non-GC-type branch of subtype_dealloc (GH-27165) (GH-27174)

The non-GC-type branch of subtype_dealloc is using the type of an object after freeing in the same unsafe way as GH-26274 fixes. (I believe the old news entry covers this change well enough.)

https://bugs.python.org/issue44184
(cherry picked from commit 074e7659f208051b6b973f7fdb654dd22b93aaa2)

Co-authored-by: T. Wouters <thomas at python.org>

files:
M Objects/typeobject.c

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index a551402b5ce53..5199c26639d9c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1344,14 +1344,22 @@ subtype_dealloc(PyObject *self)
         /* Extract the type again; tp_del may have changed it */
         type = Py_TYPE(self);
 
+        // Don't read type memory after calling basedealloc() since basedealloc()
+        // can deallocate the type and free its memory.
+        int type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE
+                                 && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE));
+
         /* Call the base tp_dealloc() */
         assert(basedealloc);
         basedealloc(self);
 
-       /* Only decref if the base type is not already a heap allocated type.
-          Otherwise, basedealloc should have decref'd it already */
-        if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE))
+        /* Can't reference self beyond this point. It's possible tp_del switched
+           our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about
+           reference counting. Only decref if the base type is not already a heap
+           allocated type. Otherwise, basedealloc should have decref'd it already */
+        if (type_needs_decref) {
             Py_DECREF(type);
+        }
 
         /* Done */
         return;



More information about the Python-checkins mailing list