[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