Skip to content

Evil call_soon may cause OOB in future_schedule_callbacks #125969

Closed
@picnixz

Description

@picnixz

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

3.12only security fixes3.13bugs and security fixes3.14bugs and security fixestopic-asynciotype-crashA hard crash of the interpreter, possibly with a core dump

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions