Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.4k
gh-126080: fix UAF ontask->task_context intask_call_step_soon due to an evilloop.__getattribute__#126120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm OK to accept the C code part of patch (after additional quick review), but I'm -1 on submitting the test, which looks extremely complicated and nearly impossible to maintain. Also due to how the test is structured it might be a pain to keep it up to date with future asyncio development.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
encukou commentedOct 30, 2024
@1st1, would it make sense to
|
willingc commentedOct 30, 2024
@encukou@1st1 I agree that these tests are overly complicated and would be better in its own test file. I also think that the tests would benefit from better naming (ridiculous setup isn't very descriptive for future maintainers). I also think a one or two line docstring of what the test is testing would be helpful too. |
picnixz commentedOct 30, 2024
I can find a better name for that :)
I assumed that referencing the issue was sufficient but I can add some comments!
Would it be possible to delay that one until we fix all UAFs or make it the priority for now (either way is fine for me).@Nico-Posada has one PR that fixes another UAF and may be working on a second one for an even more contrived crash. If you want it to be now, I can create a PR just to isolate the existing tests (and to move |
1st1 commentedOct 30, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I'm really not sure this all is worth the hassle. It's only a matter of time until someone stumbles upon this test and will not understand why it's there :) This PR tests something very abstract and not occurring in real life scenarios, so I personally think it's OK to commit the fix for the sake of having cleaner code, but on the other hand there's no need to overthink it. |
…uaf-126080# Conflicts:#Lib/test/test_asyncio/test_tasks.py
401335c to47e26c8Compare47e26c8 toaf8614dComparepicnixz commentedOct 31, 2024
I've removed the contrived test as well as the small refactorization I needed. It's much cleaner and for posterity, people can just look at02415df to get a test in the future. |
ZeroIntensity left a comment• edited by picnixz
Loading Uh oh!
There was an error while loading.Please reload this page.
edited by picnixz
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Ok, LGTM. If any future problems come up with wrappingcall_soon, let's move the job of incref'ing there instead of in the caller. For now, this is fine.
[EDITED by@picnixz]: The discussion in question (marked as resolved for visual purposes):#126120 (comment).
Nico-Posada commentedOct 31, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I'm curious if it's viable to do a refcount-based test to make sure that the refcount of our evil object is |
picnixz commentedOct 31, 2024
Could be possible and we could transform previous tests like that but it might still require some globals to know when we need to trigger the check and I suspect it'll be ugly to read =/ (haven't tried though) |
Nico-Posada commentedOct 31, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Here's something basic I was able to put together. On a build where this bug isn't patched, it says Obviously there's a lot to clean up in this, but it's MUCH smaller now and we can probably add comments explaining why it's testing for refcounts in that spot. importasyncioimporttypesimportsysfromcontextvarsimportContextasyncdefnone_coroutine():@types.coroutinedefgen():whileTrue:yieldNoneawaitgen()classTestDoneException(BaseException):passclassTestLoop:get_debug=staticmethod(lambda:False)is_running=staticmethod(lambda:True)def__getattribute__(self,name):ifname=="call_soon":print("refcount",sys.getrefcount(my_context))raiseTestDoneException()returnobject.__getattribute__(self,name)coro=none_coroutine()my_context=Context()try:task=asyncio.Task(coro,loop=TestLoop(),context=my_context,eager_start=True)exceptException:print("done") |
picnixz commentedOct 31, 2024
@1st1 Are you willing to consider this kind of test or do you prefer no test at all? if you want, we can try to remove previous tests that were also using intricate constructions just to trigger the UAF and make them adopt that kind of testing? |
encukou commentedOct 31, 2024
Refcount values can change when code is refactored, and if the refactoradds a refcount, a |
picnixz commentedOct 31, 2024
Oh right. Then I think no test is fine in this case. |
1st1 left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Approving as is without a test.
0e86655 intopython:mainUh oh!
There was an error while loading.Please reload this page.
…oon` due to an evil `loop.__getattribute__` (pythonGH-126120)(cherry picked from commit0e86655)Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
…oon` due to an evil `loop.__getattribute__` (pythonGH-126120)(cherry picked from commit0e86655)Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
GH-126250 is a backport of this pull request to the3.13 branch. |
GH-126251 is a backport of this pull request to the3.12 branch. |
…oon` due to an evil `loop.__getattribute__` (python#126120)
…oon` due to an evil `loop.__getattribute__` (python#126120)
Uh oh!
There was an error while loading.Please reload this page.
I cleaned up the PoC a bit. The pure Python implementation should not be vulnerable to that kind of shenanigans although the interpreter raises an exception upon interpreter's exit (but it doesn't crash).
task_call_step_soonin_asynciomodule.c(with admittedly ridiculous setup) #126080