gh-126703: Fix possible use after free in pycfunction freelist (GH-132319)

This commit is contained in:
Ken Jin 2025-04-09 22:49:33 +08:00 committed by GitHub
parent 3feac7a093
commit bd3aa0b9f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 6 additions and 1 deletions

View file

@ -0,0 +1 @@
Fix possible use after free in cases where a method's definition has the same lifetime as its ``self``.

View file

@ -173,12 +173,16 @@ meth_dealloc(PyObject *self)
if (m->m_weakreflist != NULL) { if (m->m_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*) m); PyObject_ClearWeakRefs((PyObject*) m);
} }
// We need to access ml_flags here rather than later.
// `m->m_ml` might have the same lifetime
// as `m_self` when it's dynamically allocated.
int ml_flags = m->m_ml->ml_flags;
// Dereference class before m_self: PyCFunction_GET_CLASS accesses // Dereference class before m_self: PyCFunction_GET_CLASS accesses
// PyMethodDef m_ml, which could be kept alive by m_self // PyMethodDef m_ml, which could be kept alive by m_self
Py_XDECREF(PyCFunction_GET_CLASS(m)); 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);
if (m->m_ml->ml_flags & METH_METHOD) { if (ml_flags & METH_METHOD) {
assert(Py_IS_TYPE(self, &PyCMethod_Type)); assert(Py_IS_TYPE(self, &PyCMethod_Type));
_Py_FREELIST_FREE(pycmethodobject, m, PyObject_GC_Del); _Py_FREELIST_FREE(pycmethodobject, m, PyObject_GC_Del);
} }