mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-143100: Fix memcpy data race in setobject.c (gh-143127)
This commit is contained in:
parent
4ee6929d60
commit
e8e044eda3
2 changed files with 16 additions and 3 deletions
|
|
@ -1420,6 +1420,17 @@ set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
return make_new_set(type, NULL);
|
||||
}
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
static void
|
||||
copy_small_table(setentry *dest, setentry *src)
|
||||
{
|
||||
for (Py_ssize_t i = 0; i < PySet_MINSIZE; i++) {
|
||||
_Py_atomic_store_ptr_release(&dest[i].key, src[i].key);
|
||||
_Py_atomic_store_ssize_relaxed(&dest[i].hash, src[i].hash);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set_swap_bodies() switches the contents of any two sets by moving their
|
||||
internal data pointers and, if needed, copying the internal smalltables.
|
||||
Semantically equivalent to:
|
||||
|
|
@ -1462,8 +1473,13 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
|
|||
|
||||
if (a_table == a->smalltable || b_table == b->smalltable) {
|
||||
memcpy(tab, a->smalltable, sizeof(tab));
|
||||
#ifndef Py_GIL_DISABLED
|
||||
memcpy(a->smalltable, b->smalltable, sizeof(tab));
|
||||
memcpy(b->smalltable, tab, sizeof(tab));
|
||||
#else
|
||||
copy_small_table(a->smalltable, b->smalltable);
|
||||
copy_small_table(b->smalltable, tab);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
|
||||
|
|
|
|||
|
|
@ -20,6 +20,3 @@ thread:pthread_create
|
|||
# PyObject_Realloc internally does memcpy which isn't atomic so can race
|
||||
# with non-locking reads. See #132070
|
||||
race:PyObject_Realloc
|
||||
|
||||
# gh-143100: set_swap_bodies in setobject.c calls memcpy, which isn't atomic
|
||||
race:set_swap_bodies
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue