https://github.com/python/cpython/commit/9e0fce413a908ce679b30e26ec1c7dfcc38c32d9
commit: 9e0fce413a908ce679b30e26ec1c7dfcc38c32d9
branch: 3.13
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: colesbury <colesb...@gmail.com>
date: 2025-03-11T23:39:29Z
summary:

[3.13] gh-131113: Fix data race in dict.popitem() (gh-131115) (#131119)

The clearing of the key, hash, and value need to use atomic operations
to avoid a data race with concurrent read operations.
(cherry picked from commit c00ac578241b3213ceb79c1f32bc83ea471f02da)

Co-authored-by: Sam Gross <colesb...@gmail.com>

files:
M Objects/dictobject.c

diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index fd8453c5d9968d..680d6beb760571 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -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)
@@ -4465,8 +4465,8 @@ dict_popitem_impl(PyDictObject *self)
                 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);
@@ -4481,9 +4481,9 @@ dict_popitem_impl(PyDictObject *self)
                 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);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to