diff options
author | Miss Skeleton (bot) <31488909+miss-islington@users.noreply.github.com> | 2020-10-12 21:29:01 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-12 21:29:01 (GMT) |
commit | 8a12503b4532e33d590ecea7eb94cd0e6b0f1488 (patch) | |
tree | edd0663323a16d3fc114a1eb434b41d1cc152080 | |
parent | 85d59644d9c53dcf4654f0177e2243b86d2a26c9 (diff) | |
download | cpython-8a12503b4532e33d590ecea7eb94cd0e6b0f1488.zip cpython-8a12503b4532e33d590ecea7eb94cd0e6b0f1488.tar.gz cpython-8a12503b4532e33d590ecea7eb94cd0e6b0f1488.tar.bz2 |
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@belgacom.net>
-rw-r--r-- | Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst | 3 | ||||
-rw-r--r-- | Objects/methodobject.c | 6 |
2 files changed, 7 insertions, 2 deletions
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 0000000..d77619f --- /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 5659f21..7b43041 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; } |