Skip to content

gh-160663: Fix UAF in visit_generation - #160667

Open
johng wants to merge 4 commits into
python:mainfrom
johng:gc-visit-objects-uaf
Open

johng wants to merge 4 commits into
python:mainfrom
johng:gc-visit-objects-uaf

Conversation

@johng

@johng johng commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Callback can free an object resulting in UAF if we have relied on the object for visiting the next item in the chain.

Fix is to use finalize_garbage approach of walking the object gc generation list directly maintaing and moving it into a tempoary list before calling callback

Callback can free an object resulting in UAF if
we have relied on the object for visiting the next
item in the chain.

Fix is to use `finalize_garbage` approach of walking
the object gc generation list directly maintaing and
moving it into a tempoary list before calling callback
Comment thread Python/gc.c Resolved
Comment thread Modules/_testcapi/gc.c Resolved
Comment thread Python/gc.c Resolved
@johng
johng requested a review from sergey-miryanov October 25, 2026 18:24
Failure case is crashing the whole test suite, also may not be
reliable
Comment thread Python/gc.c Resolved

@sergey-miryanov sergey-miryanov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM.

@sergey-miryanov

Copy link
Copy Markdown
Contributor

@nascheme Could you please take a look?

@nascheme

nascheme commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

IMHO, this is a bug the debug mode behavior, should likely not be using PySys_WriteStderr and PySys_FormatStderr if they can lead to GIL drop. I'd say the fix is not to change visit_generation but to use a different method to output the debug info. If the GC has to be written in a way that assumes the GIL can be dropped, it makes things a lot more complex. So, I think fixing the way we output the debug info is a better design.

@johng

johng commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

@nascheme just to clarify this issue is slightly different in that it's a user callback that exposed the bug rather than being specifically related to the debug_prints. Although you can use the debug_prints to expose a similar gap .PyUnstable_GC_VisitObjects accepts an arbitrary and is helping to protect against "bad" things callers can do in the callbacks.

@nascheme

nascheme commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

@nascheme just to clarify this issue is slightly different in that it's a user callback that exposed the bug

I would say we don't support callback doing that. It is quite limited what it is safe for the callback to. E.g. you can't run user level Python code from there and the APIs you are allowed to call is very limited. Basically the callback is meant for CPython to use, not for extensions to use.

Oh, I see PyUnstable_GC_VisitObjects exists. Oh dear.

@sergey-miryanov

Copy link
Copy Markdown
Contributor

@nascheme IIUC we can run user level Python code from debug_cycle if we override stderr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants