Skip to content

Commit 74e102a

Browse files
[3.15] gh-159739: Protect list storage while reporting its size (GH-160196) (#160363)
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. (cherry picked from commit d98f2cb) Co-authored-by: Jelle Zijlstra <jelle@openai.com>
1 parent 7291b84 commit 74e102a

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
@@ -3602,10 +3602,12 @@ list___sizeof___impl(PyListObject *self)
36023602
{
36033603
size_t res = _PyObject_SIZE(Py_TYPE(self));
36043604
#ifdef Py_GIL_DISABLED
3605-
PyObject **ob_item = _Py_atomic_load_ptr(&self->ob_item);
3605+
Py_BEGIN_CRITICAL_SECTION(self);
3606+
PyObject **ob_item = self->ob_item;
36063607
if (ob_item != NULL) {
36073608
res += list_capacity(ob_item) * sizeof(PyObject *);
36083609
}
3610+
Py_END_CRITICAL_SECTION();
36093611
#else
36103612
res += (size_t)self->allocated * sizeof(PyObject *);
36113613
#endif

0 commit comments

Comments
 (0)