gh-131113: Fix data race in dict.popitem() (gh-131115)

The clearing of the key, hash, and value need to use atomic operations
to avoid a data race with concurrent read operations.
This commit is contained in:
Sam Gross 2025-03-11 19:15:22 -04:00 committed by GitHub
parent ad90c5fabc
commit c00ac57824
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 8 additions and 8 deletions

View File

@ -275,10 +275,10 @@ load_keys_nentries(PyDictObject *mp)
#endif
#define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELEASE(ep->me_key, key)
#define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELEASE(ep->me_value, value)
#define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELEASE((ep)->me_key, key)
#define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELEASE((ep)->me_value, value)
#define STORE_SPLIT_VALUE(mp, idx, value) FT_ATOMIC_STORE_PTR_RELEASE(mp->ma_values->values[idx], value)
#define STORE_HASH(ep, hash) FT_ATOMIC_STORE_SSIZE_RELAXED(ep->me_hash, hash)
#define STORE_HASH(ep, hash) FT_ATOMIC_STORE_SSIZE_RELAXED((ep)->me_hash, hash)
#define STORE_KEYS_USABLE(keys, usable) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_usable, usable)
#define STORE_KEYS_NENTRIES(keys, nentries) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_nentries, nentries)
#define STORE_USED(mp, used) FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, used)
@ -4534,8 +4534,8 @@ dict_popitem_impl(PyDictObject *self)
_PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, self, key, NULL);
hash = unicode_get_hash(key);
value = ep0[i].me_value;
ep0[i].me_key = NULL;
ep0[i].me_value = NULL;
STORE_KEY(&ep0[i], NULL);
STORE_VALUE(&ep0[i], NULL);
}
else {
PyDictKeyEntry *ep0 = DK_ENTRIES(self->ma_keys);
@ -4549,9 +4549,9 @@ dict_popitem_impl(PyDictObject *self)
_PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, self, key, NULL);
hash = ep0[i].me_hash;
value = ep0[i].me_value;
ep0[i].me_key = NULL;
ep0[i].me_hash = -1;
ep0[i].me_value = NULL;
STORE_KEY(&ep0[i], NULL);
STORE_HASH(&ep0[i], -1);
STORE_VALUE(&ep0[i], NULL);
}
j = lookdict_index(self->ma_keys, hash, i);