Skip to content

Commit ef35d82

Browse files
[3.14] gh-159739: Protect list storage while reporting its size (GH-160196) (#160364)
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 09fad5d commit ef35d82

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
@@ -3560,10 +3560,12 @@ list___sizeof___impl(PyListObject *self)
35603560
{
35613561
size_t res = _PyObject_SIZE(Py_TYPE(self));
35623562
#ifdef Py_GIL_DISABLED
3563-
PyObject **ob_item = _Py_atomic_load_ptr(&self->ob_item);
3563+
Py_BEGIN_CRITICAL_SECTION(self);
3564+
PyObject **ob_item = self->ob_item;
35643565
if (ob_item != NULL) {
35653566
res += list_capacity(ob_item) * sizeof(PyObject *);
35663567
}
3568+
Py_END_CRITICAL_SECTION();
35673569
#else
35683570
res += (size_t)self->allocated * sizeof(PyObject *);
35693571
#endif

0 commit comments

Comments
 (0)