]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-120298: Fix use-after-free in `list_richcompare_impl` (GH-120303) (#120339)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 11 Jun 2024 07:22:59 +0000 (09:22 +0200)
committerGitHub <noreply@github.com>
Tue, 11 Jun 2024 07:22:59 +0000 (07:22 +0000)
gh-120298: Fix use-after-free in `list_richcompare_impl` (GH-120303)
(cherry picked from commit 141babad9b4eceb83371bf19ba3a36b50dd05250)

Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_list.py
Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst [new file with mode: 0644]
Objects/listobject.c

index 2969c6e2f98a23fabf68e972510df4c61869a515..4207f2b364542c1fc6a3ea40575c880ba644f89a 100644 (file)
@@ -229,6 +229,17 @@ class ListTest(list_tests.CommonTest):
         list4 = [1]
         self.assertFalse(list3 == list4)
 
+    def test_lt_operator_modifying_operand(self):
+        # See gh-120298
+        class evil:
+            def __lt__(self, other):
+                other.clear()
+                return NotImplemented
+
+        a = [[evil()]]
+        with self.assertRaises(TypeError):
+            a[0] < a
+
     @cpython_only
     def test_preallocation(self):
         iterable = [0] * 10
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst
new file mode 100644 (file)
index 0000000..531d395
--- /dev/null
@@ -0,0 +1,2 @@
+Fix use-after free in ``list_richcompare_impl`` which can be invoked via
+some specificly tailored evil input.
index f59abe2e644f14c599410cbb8316d548c9bfd6b6..ee724dbe1460f0dd9e68ff6210cdf435cd0bcf1f 100644 (file)
@@ -2759,7 +2759,14 @@ list_richcompare(PyObject *v, PyObject *w, int op)
     }
 
     /* Compare the final item again using the proper operator */
-    return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
+    PyObject *vitem = vl->ob_item[i];
+    PyObject *witem = wl->ob_item[i];
+    Py_INCREF(vitem);
+    Py_INCREF(witem);
+    PyObject *result = PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
+    Py_DECREF(vitem);
+    Py_DECREF(witem);
+    return result;
 }
 
 /*[clinic input]