From d4ef296726646604d4918c61f74b1fda343cc53e Mon Sep 17 00:00:00 2001 From: Li Xingru Date: Mon, 28 Oct 2024 22:21:11 +0800 Subject: [PATCH 1/3] gh-126033: Fix crash in _elementtree.c where evil tags/elements occurs --- Lib/test/test_xml_etree_c.py | 26 ++++++++++++++++++++++++++ Modules/_elementtree.c | 13 +++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 3a0fc572f457ff..44143364eed052 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -181,6 +181,32 @@ def __hash__(self): r = e.get(X()) self.assertIsNone(r) + def test_use_after_free_crash_with_evil_element(self): + # test fix for reported used-after-free issue gh-126033 + class EvilElement(cET.Element): + def __eq__(self, other): + base.clear() # this frees base->extra + return False + + base = cET.Element('a') + base.append(EvilElement('a')) + base.append(EvilElement('a')) + + with self.assertRaisesRegex(ReferenceError, r'base has been cleared during'): + base.remove(cET.Element('b')) + + def test_use_after_free_crash_with_evil_tag(self): + # test fix for reported used-after-free issue gh-126037 + class EvilTag(str): + def __eq__(self, other): + base.clear() # this frees base->extra + return False + base = cET.Element('a') + base.append(cET.Element(EvilTag('x'))) + + with self.assertRaisesRegex(ReferenceError, r'base has been cleared during'): + base.find('a') + @support.cpython_only def test_immutable_types(self): root = cET.fromstring('') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index e134e096e044b7..c02e532cad50ec 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1267,6 +1267,13 @@ _elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls, assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); + if (!self->extra) { + PyErr_SetString( + PyExc_ReferenceError, + "list.find(x): list's base has been cleared during finding"); + Py_DECREF(item); + return NULL; + } if (rc > 0) return item; Py_DECREF(item); @@ -1649,6 +1656,12 @@ _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) if (self->extra->children[i] == subelement) break; rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ); + if (!self->extra) { + PyErr_SetString( + PyExc_ReferenceError, + "list.remove(x): list's base has been cleared during removing"); + return NULL; + } if (rc > 0) break; if (rc < 0) From 2dd828ca5940a1762e94cae0e82bd4d13fcbc674 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:44:24 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst b/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst new file mode 100644 index 00000000000000..15cbaaadbce186 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst @@ -0,0 +1 @@ +Fixed use-after-crash crashes on :class:`ElementTree` which underlying __eq__() function implements clearing its base. Reported by picnixz. Patch by Xingru Li. From 2b1b009eba5f24105f3cd328cca6400daa49177c Mon Sep 17 00:00:00 2001 From: Li Xingru <52489887+nathanli97@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:51:23 +0800 Subject: [PATCH 3/3] Update NEWs rst file --- .../next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst b/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst index 15cbaaadbce186..7a8f93a79beebb 100644 --- a/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst +++ b/Misc/NEWS.d/next/Library/2024-10-28-14-44-23.gh-issue-126033.goZ_Kr.rst @@ -1 +1 @@ -Fixed use-after-crash crashes on :class:`ElementTree` which underlying __eq__() function implements clearing its base. Reported by picnixz. Patch by Xingru Li. +Fixed use-after-crash crashes on :class:`xml.etree.ElementTree` which underlying :meth:`~object.__eq__` function implements clearing its base. Reported by picnixz. Patch by Xingru Li.