Skip to content

Commit 141baba

Browse files
gh-120298: Fix use-after-free in list_richcompare_impl (#120303)
Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 9e9ee50 commit 141baba

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/test/test_list.py

+11
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,17 @@ def __eq__(self, other):
234234
list4 = [1]
235235
self.assertFalse(list3 == list4)
236236

237+
def test_lt_operator_modifying_operand(self):
238+
# See gh-120298
239+
class evil:
240+
def __lt__(self, other):
241+
other.clear()
242+
return NotImplemented
243+
244+
a = [[evil()]]
245+
with self.assertRaises(TypeError):
246+
a[0] < a
247+
237248
@cpython_only
238249
def test_preallocation(self):
239250
iterable = [0] * 10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix use-after free in ``list_richcompare_impl`` which can be invoked via
2+
some specificly tailored evil input.

Objects/listobject.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -3382,7 +3382,14 @@ list_richcompare_impl(PyObject *v, PyObject *w, int op)
33823382
}
33833383

33843384
/* Compare the final item again using the proper operator */
3385-
return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
3385+
PyObject *vitem = vl->ob_item[i];
3386+
PyObject *witem = wl->ob_item[i];
3387+
Py_INCREF(vitem);
3388+
Py_INCREF(witem);
3389+
PyObject *result = PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
3390+
Py_DECREF(vitem);
3391+
Py_DECREF(witem);
3392+
return result;
33863393
}
33873394

33883395
static PyObject *

0 commit comments

Comments
 (0)