-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-91051: fix segfault when using all 8 type watchers #107853
Conversation
@Yhg1s I think this fix should be backported to 3.12. |
7c249fa
to
e149aed
Compare
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're going to want to backport to 3.12!
Closing and re-opening to retrigger CLA checks. Sorry for the noise. |
Thanks @carljm for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
GH-107876 is a backport of this pull request to the 3.12 branch. |
The type watcher implementation adds
char tp_watched;
to thePyTypeObject
struct, and then inPyType_Modified
it assignsint bits = type->tp_watched;
and then treatsbits
as a bitset, expecting that only the low 8 bits should ever be set.On platforms where
char
is signed (e.g. x86), if the top bit intp_watched
is set, the cast toint bits
will sign-extend with 1s, and we will thus have a lot of high bits set inbits
that are not supposed to ever be set.On x86 in a debug build, without the fix in this PR, the new test hits the assertion in
PyType_Modified
that only bit positions< TYPE_MAX_WATCHERS
should be set, and aborts.The fix is simple:
tp_watched
should be defined asunsigned char
so that it is zero-extended, not sign-extended.Note that the test is carefully designed to not assume there are no type watchers already active. It doesn't attempt to register a fixed number of type watchers, instead it just registers type watchers until it reaches
TYPE_MAX_WATCHERS - 1
, the last available slot and the one that can trigger this bug (since it will set the highest bit intp_watched
when watching a type.)