diff options
author | Guido van Rossum <guido@python.org> | 2022-09-30 19:57:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-30 19:57:09 (GMT) |
commit | 63780f4599acc2c5ee8af5f37ab76c162ad21065 (patch) | |
tree | 541db070bca69edcb73a5f344b14d4493080d57d /Modules/_asynciomodule.c | |
parent | e9d63760fea8748638f6e495b5b07bd1805c9591 (diff) | |
download | cpython-63780f4599acc2c5ee8af5f37ab76c162ad21065.zip cpython-63780f4599acc2c5ee8af5f37ab76c162ad21065.tar.gz cpython-63780f4599acc2c5ee8af5f37ab76c162ad21065.tar.bz2 |
GH-97592: Fix crash in C remove_done_callback due to evil code (#97660)
Evil code could cause fut_callbacks to be cleared when PyObject_RichCompareBool is called.
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r-- | Modules/_asynciomodule.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5a5881b..90917115 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1052,7 +1052,11 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) return NULL; } - for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { + // Beware: PyObject_RichCompareBool below may change fut_callbacks. + // See GH-97592. + for (i = 0; + self->fut_callbacks != NULL && i < PyList_GET_SIZE(self->fut_callbacks); + i++) { int ret; PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); Py_INCREF(item); @@ -1071,7 +1075,8 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) } } - if (j == 0) { + // Note: fut_callbacks may have been cleared. + if (j == 0 || self->fut_callbacks == NULL) { Py_CLEAR(self->fut_callbacks); Py_DECREF(newlist); return PyLong_FromSsize_t(len + cleared_callback0); |