Skip to content

Commit

Permalink
gh-126138: Fix use-after-free in _asyncio.Task by evil `__getattrib…
Browse files Browse the repository at this point in the history
…ute__` (GH-126305)

(cherry picked from commit f032f6b)

Co-authored-by: Nico-Posada <102486290+Nico-Posada@users.noreply.github.com>
Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
  • Loading branch information
2 people authored and miss-islington committed Nov 2, 2024
1 parent 8d4ef52 commit 0f6ddd4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 20 additions & 2 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2994,8 +2994,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;
}
Expand Down Expand Up @@ -3087,8 +3096,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;
}
Expand Down

0 comments on commit 0f6ddd4

Please sign in to comment.