Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
gh-134144: Fix use-after-free in zapthreads()#134145
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
Can't use the _Py_FOR_EACH_TSTATE_UNLOCKED macro because it will reference the just-deleted tstate in order to get the next value.
python-cla-botbot commentedMay 17, 2025 • 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.
Most changes to Pythonrequire a NEWS entry. Add one using theblurb_it web app or theblurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Most changes to Pythonrequire a NEWS entry. Add one using theblurb_it web app or theblurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
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 pretty sure we can dropzapthreads
entirely, because right now the assumption is that the interpreter doesn't have any threads left. Let's hold off on this until we come to a decision on what the actual behavior should be for dangling threads.
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.
LGTM
We just need a NEWS entry.
@ZeroIntensity, regardinggh-128640, I expect we'll do that too since it solves an additional problem. However, this PR is a good idea regardless.
ZeroIntensity commentedMay 17, 2025 • 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.
We need a test as well, but I'm more worried about the use-case as given in the issue. |
b-pass commentedMay 17, 2025 • 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.
Sorry, the issue description isn't great. The thread wasn't alive, but for (PyThreadState*tstate=interp->threads.head;tstate!=NULL;tstate=tstate->next){free(tstate);} |
Right, I've noticed this before. In most cases, we get lucky because the initial thread is statically allocated on the interpreter state, so it doesn't actually cause UAF. It becomes an issue with something like |
It happens without the Ensure. I've updated the linked issue with a complete program (without an Ensure). So are you saying it's not supported to use a different |
ZeroIntensity commentedMay 17, 2025 • 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.
Yes, and you can't have any additional threads when you call I'm fine with this fix, but my point is that it's notenough. Let's add a test and then I'll approve. |
Yeah, a test would be nice. |
Misc/NEWS.d/next/C_API/2025-05-17-14-41-21.gh-issue-134144.xVpZik.rst OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
…Zik.rstCo-authored-by: Peter Bierma <zintensitydev@gmail.com>
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, let's go with this.
f2de1e6
intopython:mainUh oh!
There was an error while loading.Please reload this page.
Thanks@b-pass for the PR, and@kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14. |
(cherry picked from commitf2de1e6)Co-authored-by: b-pass <b-pass@users.noreply.github.com>
GH-134182 is a backport of this pull request to the3.14 branch. |
Uh oh!
There was an error while loading.Please reload this page.
Fixes#134144. This problem was introduced by#127077 which added
_Py_FOR_EACH_TSTATE_UNLOCKED
._Py_FOR_EACH_TSTATE_UNLOCKED
reads thetstate
at the end of each loop iteration to get thenext
value. When the loop body frees thetstate
, the result is always a use-after-free. It doesn't always crash (seems rare, actually), I guess it just depends what the allocator does with those pages during the rest of the tstate deletion.