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

Commit4fc1da1

Browse files
[3.12]gh-125966: fix use-after-free onfut->fut_callback0 due to an evil callback's__eq__ in asyncio (GH-125967) (#126048)
gh-125966: fix use-after-free on `fut->fut_callback0` due to an evil callback's `__eq__` in asyncio (GH-125967)(cherry picked from commited5059e)Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parentfdedb26 commit4fc1da1

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
@@ -988,6 +988,24 @@ def evil_call_soon(*args, **kwargs):
988988
# returns an empty list but the C implementation returns None.
989989
self.assertIn(fut._callbacks, (None, []))
990990

991+
deftest_use_after_free_on_fut_callback_0_with_evil__eq__(self):
992+
# Special thanks to Nico-Posada for the original PoC.
993+
# See https://github.com/python/cpython/issues/125966.
994+
995+
fut=self._new_future()
996+
997+
classcb_pad:
998+
def__eq__(self,other):
999+
returnTrue
1000+
1001+
classevil(cb_pad):
1002+
def__eq__(self,other):
1003+
fut.remove_done_callback(None)
1004+
returnNotImplemented
1005+
1006+
fut.add_done_callback(cb_pad())
1007+
fut.remove_done_callback(evil())
1008+
9911009
deftest_use_after_free_on_fut_callback_0_with_evil__getattribute__(self):
9921010
# see: https://github.com/python/cpython/issues/125984
9931011

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
@@ -1044,7 +1044,12 @@ _asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls,
10441044
ENSURE_FUTURE_ALIVE(state,self)
10451045

10461046
if (self->fut_callback0!=NULL) {
1047-
intcmp=PyObject_RichCompareBool(self->fut_callback0,fn,Py_EQ);
1047+
// Beware: An evil PyObject_RichCompareBool could free fut_callback0
1048+
// before a recursive call is made with that same arg. For details, see
1049+
// https://github.com/python/cpython/pull/125967#discussion_r1816593340.
1050+
PyObject*fut_callback0=Py_NewRef(self->fut_callback0);
1051+
intcmp=PyObject_RichCompareBool(fut_callback0,fn,Py_EQ);
1052+
Py_DECREF(fut_callback0);
10481053
if (cmp==-1) {
10491054
returnNULL;
10501055
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp