Skip to content

[3.14] gh-154318: Guard C recursion when hashing nested tuples and frozendicts (GH-154362) - #160131

Merged
gpshead merged 1 commit into
python:3.14from
gpshead:backport-08500b0-3.14
Oct 21, 2026
Merged

gpshead merged 1 commit into
python:3.14from
gpshead:backport-08500b0-3.14

Conversation

@gpshead

@gpshead gpshead commented Oct 21, 2026

Copy link
Copy Markdown
Member

tuple_hash() and frozendict_hash() fold each contained object's hash into
an accumulator with PyObject_Hash() inside an unguarded loop. For a deeply
nested tuple or frozendict this recurses back into the same function once
per level and overflows the C stack (SIGSEGV / STATUS_STACK_OVERFLOW)
instead of raising RecursionError.

Wrap both loops in _Py_EnterRecursiveCall() / _Py_LeaveRecursiveCall(), as
the sibling comparison and repr paths already do. The guard is placed after
the cached-hash early return, so repeated hashing of an already-hashed
tuple is unaffected.

This also covers types.GenericAlias, whose ga_hash() hashes its args
tuple and so crashed through tuple_hash().

(cherry picked from commit 08500b0)

Co-authored-by: Jason G 41053218+gianghungtien@users.noreply.github.com

…and frozendicts (pythonGH-154362)

* pythongh-154318: Guard C recursion when hashing nested tuples and frozendicts

tuple_hash() and frozendict_hash() fold each contained object's hash into
an accumulator with PyObject_Hash() inside an unguarded loop. For a deeply
nested tuple or frozendict this recurses back into the same function once
per level and overflows the C stack (SIGSEGV / STATUS_STACK_OVERFLOW)
instead of raising RecursionError.

Wrap both loops in _Py_EnterRecursiveCall() / _Py_LeaveRecursiveCall(), as
the sibling comparison and repr paths already do. The guard is placed after
the cached-hash early return, so repeated hashing of an already-hashed
tuple is unaffected.

This also covers types.GenericAlias, whose ga_hash() hashes its __args__
tuple and so crashed through tuple_hash().

(cherry picked from commit 08500b0)

Co-authored-by: Jason G <41053218+gianghungtien@users.noreply.github.com>
@bedevere-app bedevere-app Bot added the sprint label Oct 21, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Sprint Oct 21, 2026
@gpshead gpshead self-assigned this Oct 21, 2026
@gpshead
gpshead marked this pull request as ready for review October 21, 2026 23:38
@gpshead
gpshead merged commit 57f1bad into python:3.14 Oct 21, 2026
53 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Sprint Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant