Skip to content

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

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

gpshead merged 1 commit into
python:3.15from
miss-islington:backport-08500b0-3.15

Conversation

@miss-islington

Copy link
Copy Markdown
Contributor

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

…zendicts (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 enabled auto-merge (squash) October 21, 2026 22:11
@gpshead
gpshead merged commit b3e7902 into python:3.15 Oct 21, 2026
58 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Sprint Oct 21, 2026
@miss-islington
miss-islington deleted the backport-08500b0-3.15 branch October 21, 2026 22:52
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.

3 participants