bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept alive long enough (GH-22670)

This commit is contained in:
Yannick Jadoul 2020-10-12 23:06:19 +02:00 committed by GitHub
parent 24a54c0bd4
commit 04b8631d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 2 deletions

View File

@ -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`.

View File

@ -164,9 +164,11 @@ meth_dealloc(PyCFunctionObject *m)
if (m->m_weakreflist != NULL) { if (m->m_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*) m); 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_self);
Py_XDECREF(m->m_module); Py_XDECREF(m->m_module);
Py_XDECREF(PyCFunction_GET_CLASS(m));
PyObject_GC_Del(m); PyObject_GC_Del(m);
} }
@ -243,9 +245,9 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure)
static int static int
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
{ {
Py_VISIT(PyCFunction_GET_CLASS(m));
Py_VISIT(m->m_self); Py_VISIT(m->m_self);
Py_VISIT(m->m_module); Py_VISIT(m->m_module);
Py_VISIT(PyCFunction_GET_CLASS(m));
return 0; return 0;
} }