[Python-checkins] bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept alive long enough (GH-22670)
Miss Skeleton (bot)
webhook-mailer at python.org
Mon Oct 12 17:29:12 EDT 2020
https://github.com/python/cpython/commit/8a12503b4532e33d590ecea7eb94cd0e6b0f1488
commit: 8a12503b4532e33d590ecea7eb94cd0e6b0f1488
branch: 3.9
author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-10-12T14:29:01-07:00
summary:
bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept alive long enough (GH-22670)
(cherry picked from commit 04b8631d84a870dda456ef86039c1baf34d08500)
Co-authored-by: Yannick Jadoul <yannick.jadoul at belgacom.net>
files:
A Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst
M Objects/methodobject.c
diff --git a/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst b/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst
new file mode 100644
index 0000000000000..d77619f64bb17
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst
@@ -0,0 +1,3 @@
+Fix potential crash in deallocating method objects when dynamically
+allocated `PyMethodDef`'s lifetime is managed through the ``self``
+argument of a `PyCFunction`.
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 5659f2143d182..7b430416c5a04 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -164,9 +164,11 @@ meth_dealloc(PyCFunctionObject *m)
if (m->m_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*) m);
}
+ // Dereference class before m_self: PyCFunction_GET_CLASS accesses
+ // PyMethodDef m_ml, which could be kept alive by m_self
+ Py_XDECREF(PyCFunction_GET_CLASS(m));
Py_XDECREF(m->m_self);
Py_XDECREF(m->m_module);
- Py_XDECREF(PyCFunction_GET_CLASS(m));
PyObject_GC_Del(m);
}
@@ -243,9 +245,9 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure)
static int
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
{
+ Py_VISIT(PyCFunction_GET_CLASS(m));
Py_VISIT(m->m_self);
Py_VISIT(m->m_module);
- Py_VISIT(PyCFunction_GET_CLASS(m));
return 0;
}
More information about the Python-checkins
mailing list