Skip to content

Commit d98f2cb

Browse files
authored
gh-159739: Protect list storage while reporting its size (#160196)
On free-threaded builds, list.__sizeof__() reads an allocation header through an atomically loaded storage pointer. The list's owner can resize and free that storage between the load and the header read, producing invalid size data or an invalid memory read. Hold the list lock while inspecting the allocation. Backport to 3.15 and 3.14.
1 parent 4df47d8 commit d98f2cb

2 files changed

Lines changed: 4 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a race in ``list.__sizeof__()`` when a list is concurrently resized on a free-threaded build.

‎Objects/listobject.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3658,10 +3658,12 @@ list___sizeof___impl(PyListObject *self)
36583658
{
36593659
size_t res = _PyObject_SIZE(Py_TYPE(self));
36603660
#ifdef Py_GIL_DISABLED
3661-
PyObject **ob_item = _Py_atomic_load_ptr(&self->ob_item);
3661+
Py_BEGIN_CRITICAL_SECTION(self);
3662+
PyObject **ob_item = self->ob_item;
36623663
if (ob_item != NULL) {
36633664
res += list_capacity(ob_item) * sizeof(PyObject *);
36643665
}
3666+
Py_END_CRITICAL_SECTION();
36653667
#else
36663668
res += (size_t)self->allocated * sizeof(PyObject *);
36673669
#endif

0 commit comments

Comments
 (0)