New submission from Yannick Jadoul <yannick.jad...@gmail.com>:

In Python 3.9, the line `Py_XDECREF(PyCFunction_GET_CLASS(m));` was added to 
`meth_dealloc` (in `methodobject.c`). Unfortunately for pybind11, it's inserted 
exactly two lines too low, since it accesses the `PyMethodDef` and we store the 
`PyMethodDef` instance in the capsule that's used as `self`-argument of the 
`PyCFunction`.

Result: UB, since `Py_XDECREF(m->m_self);` brings down the refcount of the 
capsule to 0 and (indirectly) frees the `PyMethodDef`, while its contents are 
now still accessed.

>From the pybind11 perspective, it would be optimal if this could be fixed in 
>CPython itself, by moving up this one `Py_XDECREF` 2 lines. This would a) be 
>more efficient than creating a workaround, and b) allow old, existing versions 
>of pybind11 to work with Python 3.9 (well, 3.9.1, then, hopefully); the user 
>base of pybind11 has grown quite a bit and now includes giants like scipy or 
>some Google libraries.
I will make a PR implementing this, soon.

If there's a different, recommended way of creating these `PyCFunctionObject`s 
dynamically and cleaning up the `PyMethodDef`, we'd be interested as well, to 
make sure these kinds of breakages are avoided in the future.

Apologies for only figuring out now how to debug this, using valgrind. Up until 
yesterday, we only saw some failures in CI on macOS, but it was hard to 
reproduce and debug locally.


- Related issue: https://bugs.python.org/issue41237
- pybind11 issue: https://github.com/pybind/pybind11/issues/2558
- pybind11 PR: https://github.com/pybind/pybind11/pull/2576

----------
components: C API, Interpreter Core
messages: 378500
nosy: YannickJadoul
priority: normal
severity: normal
status: open
title: Order of decrementing reference counts in meth_dealloc
type: crash
versions: Python 3.10, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue42015>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to