Closed
Description
Crash report
Bug description:
In future_schedule_callbacks
, the length of the callback list is assumed to be constant, but an evil call_soon
can make it change.
PoC:
import asyncio
called_on_fut_callback0 = False
pad = lambda: ...
def evil_call_soon(*args, **kwargs):
global called_on_fut_callback0
if called_on_fut_callback0:
# Called when handling fut->fut_callbacks[0]
# and mutates the length fut->fut_callbacks.
fut.remove_done_callback(int)
fut.remove_done_callback(pad)
else:
called_on_fut_callback0 = True
fake_event_loop = lambda: ...
fake_event_loop.call_soon = evil_call_soon
fake_event_loop.get_debug = lambda: False # suppress traceback
fut = asyncio.Future(loop=fake_event_loop)
fut.add_done_callback(str) # sets fut->fut_callback0
fut.add_done_callback(int) # sets fut->fut_callbacks[0]
fut.add_done_callback(pad) # sets fut->fut_callbacks[1]
fut.add_done_callback(pad) # sets fut->fut_callbacks[2]
fut.set_result("boom")
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status
Done