https://github.com/python/cpython/commit/f032f6ba8fec6fab35edeec0eb40cd73e9d58928
commit: f032f6ba8fec6fab35edeec0eb40cd73e9d58928
branch: main
author: Nico-Posada <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2024-11-02T13:16:00+05:30
summary:

gh-126138: Fix use-after-free in `_asyncio.Task` by evil `__getattribute__` 
(#126305)

Co-authored-by: Carol Willing <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-01-14-31-41.gh-issue-126138.yTniOG.rst
M Modules/_asynciomodule.c

diff --git 
a/Misc/NEWS.d/next/Library/2024-11-01-14-31-41.gh-issue-126138.yTniOG.rst 
b/Misc/NEWS.d/next/Library/2024-11-01-14-31-41.gh-issue-126138.yTniOG.rst
new file mode 100644
index 00000000000000..459eebc82bd42a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-01-14-31-41.gh-issue-126138.yTniOG.rst
@@ -0,0 +1,3 @@
+Fix a use-after-free crash on :class:`asyncio.Task` objects
+whose underlying coroutine yields an object that implements
+an evil :meth:`~object.__getattribute__`. Patch by Nico Posada.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 7483e9c0f43acf..214c18e966c4c1 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2967,8 +2967,17 @@ task_step_handle_result_impl(asyncio_state *state, 
TaskObj *task, PyObject *resu
         if (task->task_must_cancel) {
             PyObject *r;
             int is_true;
+
+            // Beware: An evil `__getattribute__` could
+            // prematurely delete task->task_cancel_msg before the
+            // task is cancelled, thereby causing a UAF crash.
+            //
+            // See https://github.com/python/cpython/issues/126138
+            PyObject *task_cancel_msg = Py_NewRef(task->task_cancel_msg);
             r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel),
-                                             task->task_cancel_msg);
+                                          task_cancel_msg);
+            Py_DECREF(task_cancel_msg);
+
             if (r == NULL) {
                 return NULL;
             }
@@ -3060,8 +3069,17 @@ task_step_handle_result_impl(asyncio_state *state, 
TaskObj *task, PyObject *resu
         if (task->task_must_cancel) {
             PyObject *r;
             int is_true;
+
+            // Beware: An evil `__getattribute__` could
+            // prematurely delete task->task_cancel_msg before the
+            // task is cancelled, thereby causing a UAF crash.
+            //
+            // See https://github.com/python/cpython/issues/126138
+            PyObject *task_cancel_msg = Py_NewRef(task->task_cancel_msg);
             r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel),
-                                             task->task_cancel_msg);
+                                          task_cancel_msg);
+            Py_DECREF(task_cancel_msg);
+
             if (r == NULL) {
                 return NULL;
             }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to