https://github.com/python/cpython/commit/f58d5ab881541f2b244fe991dcbfbb749604692b
commit: f58d5ab881541f2b244fe991dcbfbb749604692b
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2024-11-02T08:09:18Z
summary:

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

gh-126138: Fix use-after-free in `_asyncio.Task` by evil `__getattribute__` 
(GH-126305)
(cherry picked from commit f032f6ba8fec6fab35edeec0eb40cd73e9d58928)

Co-authored-by: Nico-Posada <[email protected]>
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 40fe7d839552cc..79896c6b9fdd92 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2907,8 +2907,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;
             }
@@ -3000,8 +3009,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