]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept...
authorYannick Jadoul <yannick.jadoul@belgacom.net>
Mon, 12 Oct 2020 21:06:19 +0000 (23:06 +0200)
committerGitHub <noreply@github.com>
Mon, 12 Oct 2020 21:06:19 +0000 (00:06 +0300)
Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst [new file with mode: 0644]
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 (file)
index 0000000..d77619f
--- /dev/null
@@ -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`.
index 5659f2143d1823396d7be2d1e115cde21ee5e0a2..7b430416c5a048715c1e8e91b4128c46ca25f828 100644 (file)
@@ -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;
 }