https://github.com/python/cpython/commit/0559339ccdc76a63dcbd14eb2d60a41f493a1ded
commit: 0559339ccdc76a63dcbd14eb2d60a41f493a1ded
branch: main
author: Sam Gross <[email protected]>
committer: colesbury <[email protected]>
date: 2025-02-13T11:50:45-05:00
summary:
gh-130019: Fix data race in _PyType_AllocNoTrack (gh-130058)
The reference count fields, such as `ob_tid` and `ob_ref_shared`, may be
accessed concurrently in the free threading build by a `_Py_TryXGetRef`
or similar operation. The PyObject header fields will be initialized by
`_PyObject_Init`, so only call `memset()` to zero-initialize the remainder
of the allocation.
files:
M Objects/typeobject.c
M Python/gc.c
M Python/gc_free_threading.c
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 1484d9b33417b2..818a00708b5d3d 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2251,7 +2251,9 @@ _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t
nitems)
if (PyType_IS_GC(type)) {
_PyObject_GC_Link(obj);
}
- memset(obj, '\0', size);
+ // Zero out the object after the PyObject header. The header fields are
+ // initialized by _PyObject_Init[Var]().
+ memset((char *)obj + sizeof(PyObject), 0, size - sizeof(PyObject));
if (type->tp_itemsize == 0) {
_PyObject_Init(obj, type);
diff --git a/Python/gc.c b/Python/gc.c
index 68879b9efa14c6..7faf368f35898a 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -2310,11 +2310,12 @@ PyObject *
PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *tp, size_t extra_size)
{
size_t presize = _PyType_PreHeaderSize(tp);
- PyObject *op = gc_alloc(tp, _PyObject_SIZE(tp) + extra_size, presize);
+ size_t size = _PyObject_SIZE(tp) + extra_size;
+ PyObject *op = gc_alloc(tp, size, presize);
if (op == NULL) {
return NULL;
}
- memset(op, 0, _PyObject_SIZE(tp) + extra_size);
+ memset((char *)op + sizeof(PyObject), 0, size - sizeof(PyObject));
_PyObject_Init(op, tp);
return op;
}
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 0d6fddb5705b4a..694f97d5c57334 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -2595,11 +2595,12 @@ PyObject *
PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *tp, size_t extra_size)
{
size_t presize = _PyType_PreHeaderSize(tp);
- PyObject *op = gc_alloc(tp, _PyObject_SIZE(tp) + extra_size, presize);
+ size_t size = _PyObject_SIZE(tp) + extra_size;
+ PyObject *op = gc_alloc(tp, size, presize);
if (op == NULL) {
return NULL;
}
- memset(op, 0, _PyObject_SIZE(tp) + extra_size);
+ memset((char *)op + sizeof(PyObject), 0, size - sizeof(PyObject));
_PyObject_Init(op, tp);
return op;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]