Skip to content

gh-159285: Fix crash when copying an empty dict fails with MemoryError - #159286

Merged
methane merged 1 commit into
python:mainfrom
christianaurichzm:gh-159285-dict-copy-no-memory
Oct 13, 2026
Merged

methane merged 1 commit into
python:mainfrom
christianaurichzm:gh-159285-dict-copy-no-memory

Conversation

@christianaurichzm

@christianaurichzm christianaurichzm commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #159285

copy_lock_held_untracked() handles the empty-dict case by allocating a new dict and then asserting !_PyObject_GC_IS_TRACKED(d). When the allocation fails, d is NULL and the assertion dereferences it, so a debug build segfaults instead of raising MemoryError. This is reachable from dict.copy(), PyDict_Copy() and _PyDict_CopyAsDict(), which type() uses for the class namespace.

This change lets the assertion accept NULL. Release builds are unchanged, since they already returned NULL with MemoryError set.

Verification

  • The new test in test_dict segfaults an unpatched debug build and passes with the fix, also with -R 3:3.
  • test_dict, test_capi.test_dict, test_class, test_descr, test_types and test_gc pass on a debug build.

…ryError

copy_lock_held_untracked() asserted that the new empty dict was not
tracked by the GC without checking whether its allocation had failed,
so a debug build dereferenced NULL instead of raising MemoryError. This
affected dict.copy(), PyDict_Copy() and _PyDict_CopyAsDict(), which
type() uses for the class namespace.
@methane methane added the needs backport to 3.15 bugs and security fixes label Oct 13, 2026
@methane
methane enabled auto-merge (squash) October 13, 2026 03:01
@methane
methane merged commit f9132f1 into python:main Oct 13, 2026
63 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @christianaurichzm for the PR, and @methane for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖

@bedevere-app

bedevere-app Bot commented Oct 13, 2026

Copy link
Copy Markdown

GH-159287 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Oct 13, 2026
methane pushed a commit that referenced this pull request Oct 13, 2026
GH-159286)

copy_lock_held_untracked() asserted that the new empty dict was not
tracked by the GC without checking whether its allocation had failed,
so a debug build dereferenced NULL instead of raising MemoryError. This
affected dict.copy(), PyDict_Copy() and _PyDict_CopyAsDict(), which
type() uses for the class namespace.
(cherry picked from commit f9132f1)

Co-authored-by: Christian Aurich Zanettini Martins <christian.aurichzm@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copying an empty dict segfaults on MemoryError in debug builds

2 participants