summaryrefslogtreecommitdiffstats
path: root/Modules/_asynciomodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2022-09-30 19:57:09 (GMT)
committerGitHub <noreply@github.com>2022-09-30 19:57:09 (GMT)
commit63780f4599acc2c5ee8af5f37ab76c162ad21065 (patch)
tree541db070bca69edcb73a5f344b14d4493080d57d /Modules/_asynciomodule.c
parente9d63760fea8748638f6e495b5b07bd1805c9591 (diff)
downloadcpython-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.c9
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);