-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Description
Problem
This is a long standing issue of the _asyncio accelerator module where _asyncio.Task and _asyncio.Future define tp_init slot instead of tp_new slot for creating the object. This allows malicious code to re-initialize objects while tasks and futures are executing which can crash the interpreter because internally the fields of tasks and futures are accessed using borrowed references for performance.
There have been multiple reports of this where we previously changed the code to use strong references like #126080 but still there are a lot of places where borrowed references to loop is used etc.
IMO changing the code to use strong references is not the solution here, instead we should make tasks and futures immutable at C level so that this issue would not exist in the first place. Avoiding strong references is also important for performance especially in free-threading.
Proposal
Historically _asyncio.Task and _asyncio.Future define tp_init rather than tp_new, so we cannot change it to use tp_new as it would break compatibility with subclasses. To preserve backward compatibility I propose to to instead allow tp_init to be called exactly once and if user tries to initialize it again, raise RuntimeError that task cannot be re-initialized. This would prevent all these issues while preserving backwards compatibility and performance.
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status