Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commited5059e

Browse files
authored
gh-125966: fix use-after-free onfut->fut_callback0 due to an evil callback's__eq__ in asyncio (#125967)
1 parent0922a4a commited5059e

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

‎Lib/test/test_asyncio/test_futures.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,24 @@ def evil_call_soon(*args, **kwargs):
999999
# returns an empty list but the C implementation returns None.
10001000
self.assertIn(fut._callbacks, (None, []))
10011001

1002+
deftest_use_after_free_on_fut_callback_0_with_evil__eq__(self):
1003+
# Special thanks to Nico-Posada for the original PoC.
1004+
# See https://github.com/python/cpython/issues/125966.
1005+
1006+
fut=self._new_future()
1007+
1008+
classcb_pad:
1009+
def__eq__(self,other):
1010+
returnTrue
1011+
1012+
classevil(cb_pad):
1013+
def__eq__(self,other):
1014+
fut.remove_done_callback(None)
1015+
returnNotImplemented
1016+
1017+
fut.add_done_callback(cb_pad())
1018+
fut.remove_done_callback(evil())
1019+
10021020
deftest_use_after_free_on_fut_callback_0_with_evil__getattribute__(self):
10031021
# see: https://github.com/python/cpython/issues/125984
10041022

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a use-after-free crash in:meth:`asyncio.Future.remove_done_callback`.
2+
Patch by Bénédikt Tran.

‎Modules/_asynciomodule.c‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,12 @@ _asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls,
10191019
ENSURE_FUTURE_ALIVE(state,self)
10201020

10211021
if (self->fut_callback0!=NULL) {
1022-
intcmp=PyObject_RichCompareBool(self->fut_callback0,fn,Py_EQ);
1022+
// Beware: An evil PyObject_RichCompareBool could free fut_callback0
1023+
// before a recursive call is made with that same arg. For details, see
1024+
// https://github.com/python/cpython/pull/125967#discussion_r1816593340.
1025+
PyObject*fut_callback0=Py_NewRef(self->fut_callback0);
1026+
intcmp=PyObject_RichCompareBool(fut_callback0,fn,Py_EQ);
1027+
Py_DECREF(fut_callback0);
10231028
if (cmp==-1) {
10241029
returnNULL;
10251030
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp