Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
Description
AfterRETURN_GENERATOR executes, the new generator's_PyInterpreterFrame has aprevious member that still points to the caller's_PyInterpreterFrame. However, this is incorrect; it should beNULL, since the generator's frame isn't actually running anymore. This dangling pointer is dangerous, and can lead to hard crashes of the interpreter. Example:
Python3.11.0rc2 (tags/v3.11.0rc2:ed7c3ff156,Oct22022,07:05:44) [GCC9.3.0]onlinuxType"help","copyright","credits"or"license"formoreinformation.>>>defg():...yield...>>>deff():...returng()...>>>gen=f()
This should beNone, but instead it refers to a dead_PyInterpreterFrame from the previous call:
>>>gen.gi_frame.f_back<frameat0x7f74318c6e80,file'<stdin>',line2,codef>
Making other calls "updates" this frame, since it just points to an arbitrary location in the stack:
>>>defspam():...pass...>>>spam()>>>gen.gi_frame.f_back<frameat0x7f7431ab93f0,file'<stdin>',line2,codespam>
It's also quite simple to corrupt:
>>>delspam>>>gen.gi_frame.f_back<frameat0x7f7431ab93f0,file'<stdin>',line1629515630,code'<stdin>'>>>>gen.gi_frame.f_back.f_codeSegmentationfault
This bug also appears to affectPyAsyncGen_New,PyCoro_New,PyGen_New, andPyGen_NewWithQualName.
The fix is simple: setframe->previous toNULL after calls to_PyFrame_Copy. I'll open a PR at the sprint tomorrow.
Metadata
Metadata
Assignees
Labels
Projects
Status
Status