]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44184: Apply GH-26274 to the non-GC-type branch of subtype_dealloc (GH-27165)
authorT. Wouters <thomas@python.org>
Thu, 15 Jul 2021 22:40:57 +0000 (00:40 +0200)
committerGitHub <noreply@github.com>
Thu, 15 Jul 2021 22:40:57 +0000 (00:40 +0200)
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

Objects/typeobject.c

index 02ea618670d8f9be049dd5785301bbf1ffaf86b7..3331fee4252deed88465db1260be4909f63f7f21 100644 (file)
@@ -1368,14 +1368,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;