| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…uilds When a shared dict is resized, the old keys/values tables are retained via QSBR so concurrent lock-free readers can still touch the memory. Those tables previously kept live me_key/me_value pointers after ownership was transferred or released, so a later update could free the objects while a reader (including LOAD_ATTR_WITH_HINT) still held a stale table — a use-after-free. Clear entry slots before QSBR-delayed free, null before decref in dictkeys_decref, re-validate ma_keys after acquiring a value in the hint fast path and threadsafe unicode lookup, and treat a NULL me_key under an active index as KEY_CHANGED so poisoned tables force a locked retry rather than a false miss. This addresses finding (124) from the free-threading race audit.
|
The following commit authors need to sign the Contributor License Agreement: |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
Fixes finding (124) from #149816: a use-after-free when a free-threaded dict is resized while another thread does lock-free lookups (including specialized LOAD_ATTR_WITH_HINT).
Root cause
On resize of a shared dict, the old PyDictKeysObject / values array is retained via QSBR so concurrent lock-free readers can still touch the table memory. Those tables previously kept live me_key / me_value pointers after ownership was transferred to the new table (or released on clear). A later update of the dict can free those objects while a reader still holds a stale table pointer and tries to incref them — UAF / ABA.
Fix
Structural hardening of the reclaim path, not a one-line band-aid:
Tests
Both stress concurrent resize + lock-free / specialized reads under free-threading (and TSAN in local builds).
Test plan