Skip to content

gh-142637: Fix use-after-free in OrderedDict lookups with a re-entrant __eq__ - #160275

Closed
AnKiT-GaRG2 wants to merge 1 commit into
python:mainfrom
AnKiT-GaRG2:gh-142637-odict-reentrant-eq
Closed

AnKiT-GaRG2 wants to merge 1 commit into
python:mainfrom
AnKiT-GaRG2:gh-142637-odict-reentrant-eq

Conversation

@AnKiT-GaRG2

Copy link
Copy Markdown

Fixes the heap-use-after-free reported in #142637 for del od[key], od.pop(key) and od.move_to_end(key).

Looking up a key can call its __eq__, which may call od.clear() and so replace ma_keys:

  • _odict_get_index_raw() read dk_nentries from a keys pointer cached before the lookup, which was freed by then.
  • _odict_get_index() returned an index into an od_fast_nodes table sized for the old keys.

_odict_get_index() now looks the key up again when the keys were replaced during the lookup, which is what dict does, and _odict_get_index_raw() reads the current keys. The operations then behave like their dict counterparts: the key is not found, so KeyError is raised.

In the issue, @picnixz suggested either matching dict or raising RuntimeError as in gh-121329. I went with matching dict because it needs no new exception, but I can switch to RuntimeError if @rhettinger prefers that.

Tested with a debug build and a --with-address-sanitizer build: the three reproducers from the issue report a heap-use-after-free in _odict_get_index_raw without the change, and none with it. test_ordered_dict, test_dict and test_collections pass under ASAN.

…entrant __eq__

Looking up a key can call its __eq__ method, which may clear the dictionary and so replace its keys. _odict_get_index_raw() then read the freed keys, and _odict_get_index() used an od_fast_nodes table that no longer matched them. Look the key up again when the keys were replaced, as dict does.
@python-cla-bot

python-cla-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@picnixz

picnixz commented Oct 22, 2026

Copy link
Copy Markdown
Member

Don't open PRs if the issue is still being discussed especially not if they are simply LLM generated.

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.

2 participants