diff --git a/SOURCES/00406-cve-2022-48565.patch b/SOURCES/00406-cve-2022-48565.patch new file mode 100644 index 0000000..1f102b7 --- /dev/null +++ b/SOURCES/00406-cve-2022-48565.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ned Deily +Date: Fri, 6 Oct 2023 12:23:43 +0200 +Subject: [PATCH] 00406-cve-2022-48565.patch + +Reject XML entity declarations in plist files +CVE-2022-48565: XML External Entity in XML processing plistlib module +Backported from https://github.com/python/cpython/commit/a158fb9c5138 +Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2022-48565 + +Co-authored-by: Ronald Oussoren +Co-authored-by: Lumir Balhar +--- + Lib/plistlib.py | 12 ++++++++++++ + Lib/test/test_plistlib.py | 18 ++++++++++++++++++ + .../2020-10-19-10-56-27.bpo-42051.EU_B7u.rst | 3 +++ + 3 files changed, 33 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2020-10-19-10-56-27.bpo-42051.EU_B7u.rst + +diff --git a/Lib/plistlib.py b/Lib/plistlib.py +index 42897b8da8b..73fca1d4714 100644 +--- a/Lib/plistlib.py ++++ b/Lib/plistlib.py +@@ -390,6 +390,11 @@ class Data: + return "%s(%s)" % (self.__class__.__name__, repr(self.data)) + + ++class InvalidFileException (ValueError): ++ def __init__(self, message="Invalid file"): ++ ValueError.__init__(self, message) ++ ++ + class PlistParser: + + def __init__(self): +@@ -403,9 +408,16 @@ class PlistParser: + parser.StartElementHandler = self.handleBeginElement + parser.EndElementHandler = self.handleEndElement + parser.CharacterDataHandler = self.handleData ++ parser.EntityDeclHandler = self.handle_entity_decl + parser.ParseFile(fileobj) + return self.root + ++ def handle_entity_decl(self, entity_name, is_parameter_entity, value, base, system_id, public_id, notation_name): ++ # Reject plist files with entity declarations to avoid XML vulnerabilies in expat. ++ # Regular plist files don't contain those declerations, and Apple's plutil tool does not ++ # accept them either. ++ raise InvalidFileException("XML entity declarations are not supported in plist files") ++ + def handleBeginElement(self, element, attrs): + self.data = [] + handler = getattr(self, "begin_" + element, None) +diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py +index 7859ad05723..bcdae924d91 100644 +--- a/Lib/test/test_plistlib.py ++++ b/Lib/test/test_plistlib.py +@@ -86,6 +86,19 @@ TESTDATA = """ + + """.replace(" " * 8, "\t") # Apple as well as plistlib.py output hard tabs + ++XML_PLIST_WITH_ENTITY=b'''\ ++ ++ ++ ]> ++ ++ ++ A ++ &entity; ++ ++ ++''' ++ + + class TestPlistlib(unittest.TestCase): + +@@ -195,6 +208,11 @@ class TestPlistlib(unittest.TestCase): + self.assertEqual(test1, result1) + self.assertEqual(test2, result2) + ++ def test_xml_plist_with_entity_decl(self): ++ with self.assertRaisesRegexp(plistlib.InvalidFileException, ++ "XML entity declarations are not supported"): ++ plistlib.readPlistFromString(XML_PLIST_WITH_ENTITY) ++ + + def test_main(): + test_support.run_unittest(TestPlistlib) +diff --git a/Misc/NEWS.d/next/Security/2020-10-19-10-56-27.bpo-42051.EU_B7u.rst b/Misc/NEWS.d/next/Security/2020-10-19-10-56-27.bpo-42051.EU_B7u.rst +new file mode 100644 +index 00000000000..31b44b229f6 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2020-10-19-10-56-27.bpo-42051.EU_B7u.rst +@@ -0,0 +1,3 @@ ++The :mod:`plistlib` module no longer accepts entity declarations in XML ++plist files to avoid XML vulnerabilities. This should not affect users as ++entity declarations are not used in regular plist files. +\ No newline at end of file diff --git a/SOURCES/00408-cve-2022-48560.patch b/SOURCES/00408-cve-2022-48560.patch new file mode 100644 index 0000000..d379d02 --- /dev/null +++ b/SOURCES/00408-cve-2022-48560.patch @@ -0,0 +1,136 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Thu, 23 Nov 2023 13:25:44 +0100 +Subject: [PATCH] 00408-cve-2022-48560.patch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Security fix for CVE-2022-48560: python3: use after free in heappushpop() +of heapq module +Resolved upstream: https://github.com/python/cpython/issues/83602 + +Backported from Python 3.6.11. + +Co-authored-by: Pablo Galindo +Co-authored-by: Lumír Balhar +--- + Lib/test/test_heapq.py | 32 ++++++++++++++++++++++++++++++++ + Modules/_heapqmodule.c | 31 ++++++++++++++++++++++++------- + 2 files changed, 56 insertions(+), 7 deletions(-) + +diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py +index c4de593bb82..29cefb5d1a6 100644 +--- a/Lib/test/test_heapq.py ++++ b/Lib/test/test_heapq.py +@@ -396,6 +396,38 @@ class TestErrorHandling(TestCase): + with self.assertRaises((IndexError, RuntimeError)): + self.module.heappop(heap) + ++ def test_comparison_operator_modifiying_heap(self): ++ # See bpo-39421: Strong references need to be taken ++ # when comparing objects as they can alter the heap ++ class EvilClass(int): ++ def __lt__(self, o): ++ heap[:] = [] ++ return NotImplemented ++ ++ heap = [] ++ self.module.heappush(heap, EvilClass(0)) ++ self.assertRaises(IndexError, self.module.heappushpop, heap, 1) ++ ++ def test_comparison_operator_modifiying_heap_two_heaps(self): ++ ++ class h(int): ++ def __lt__(self, o): ++ list2[:] = [] ++ return NotImplemented ++ ++ class g(int): ++ def __lt__(self, o): ++ list1[:] = [] ++ return NotImplemented ++ ++ list1, list2 = [], [] ++ ++ self.module.heappush(list1, h(0)) ++ self.module.heappush(list2, g(0)) ++ ++ self.assertRaises((IndexError, RuntimeError), self.module.heappush, list1, g(1)) ++ self.assertRaises((IndexError, RuntimeError), self.module.heappush, list2, h(1)) ++ + + class TestErrorHandlingPython(TestErrorHandling): + module = py_heapq +diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c +index 5b0ef691545..c013aee1ebf 100644 +--- a/Modules/_heapqmodule.c ++++ b/Modules/_heapqmodule.c +@@ -52,7 +52,11 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) + while (pos > startpos) { + parentpos = (pos - 1) >> 1; + parent = PyList_GET_ITEM(heap, parentpos); ++ Py_INCREF(newitem); ++ Py_INCREF(parent); + cmp = cmp_lt(newitem, parent); ++ Py_DECREF(parent); ++ Py_DECREF(newitem); + if (cmp == -1) + return -1; + if (size != PyList_GET_SIZE(heap)) { +@@ -93,9 +97,13 @@ _siftup(PyListObject *heap, Py_ssize_t pos) + childpos = 2*pos + 1; /* leftmost child position */ + rightpos = childpos + 1; + if (rightpos < endpos) { +- cmp = cmp_lt( +- PyList_GET_ITEM(heap, childpos), +- PyList_GET_ITEM(heap, rightpos)); ++ PyObject* a = PyList_GET_ITEM(heap, childpos); ++ PyObject* b = PyList_GET_ITEM(heap, rightpos); ++ Py_INCREF(a); ++ Py_INCREF(b); ++ cmp = cmp_lt(a, b); ++ Py_DECREF(a); ++ Py_DECREF(b); + if (cmp == -1) + return -1; + if (cmp == 0) +@@ -236,7 +244,10 @@ heappushpop(PyObject *self, PyObject *args) + return item; + } + +- cmp = cmp_lt(PyList_GET_ITEM(heap, 0), item); ++ PyObject* top = PyList_GET_ITEM(heap, 0); ++ Py_INCREF(top); ++ cmp = cmp_lt(top, item); ++ Py_DECREF(top); + if (cmp == -1) + return NULL; + if (cmp == 0) { +@@ -395,7 +406,9 @@ _siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) + while (pos > startpos){ + parentpos = (pos - 1) >> 1; + parent = PyList_GET_ITEM(heap, parentpos); ++ Py_INCREF(parent); + cmp = cmp_lt(parent, newitem); ++ Py_DECREF(parent); + if (cmp == -1) { + Py_DECREF(newitem); + return -1; +@@ -436,9 +449,13 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos) + childpos = 2*pos + 1; /* leftmost child position */ + rightpos = childpos + 1; + if (rightpos < endpos) { +- cmp = cmp_lt( +- PyList_GET_ITEM(heap, rightpos), +- PyList_GET_ITEM(heap, childpos)); ++ PyObject* a = PyList_GET_ITEM(heap, rightpos); ++ PyObject* b = PyList_GET_ITEM(heap, childpos); ++ Py_INCREF(a); ++ Py_INCREF(b); ++ cmp = cmp_lt(a, b); ++ Py_DECREF(a); ++ Py_DECREF(b); + if (cmp == -1) { + Py_DECREF(newitem); + return -1; diff --git a/SPECS/python2.spec b/SPECS/python2.spec index d7f74e6..cb303ba 100644 --- a/SPECS/python2.spec +++ b/SPECS/python2.spec @@ -104,7 +104,7 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{python} # Remember to also rebase python2-docs when changing this: Version: 2.7.18 -Release: 15%{?dist} +Release: 17%{?dist} License: Python Group: Development/Languages Requires: %{python}-libs%{?_isa} = %{version}-%{release} @@ -838,6 +838,21 @@ Patch399: 00399-cve-2023-24329.patch # Backported from Python 3.8 Patch404: 00404-cve-2023-40217.patch +# 00406 # 33d46d8ceb68210f6234f26f3465c8556c0b6ccb +# Reject XML entity declarations in plist files +# CVE-2022-48565: XML External Entity in XML processing plistlib module +# Backported from https://github.com/python/cpython/commit/a158fb9c5138 +# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2022-48565 +Patch406: 00406-cve-2022-48565.patch + +# 00408 # 7cfb7e151bb64b384c47bfe0dddf5c2d6837772f +# Security fix for CVE-2022-48560: python3: use after free in heappushpop() +# of heapq module +# Resolved upstream: https://github.com/python/cpython/issues/83602 +# +# Backported from Python 3.6.11. +Patch408: 00408-cve-2022-48560.patch + # (New patches go here ^^^) # # When adding new patches to "python2" and "python3" in Fedora, EL, etc., @@ -1176,6 +1191,8 @@ git apply %{PATCH351} %patch394 -p1 %patch399 -p1 %patch404 -p1 +%patch406 -p1 +%patch408 -p1 # This shouldn't be necesarry, but is right now (2.2a3) @@ -2115,6 +2132,14 @@ fi # ====================================================== %changelog +* Thu Nov 30 2023 Lumír Balhar - 2.7.18-17 +- Security fix for CVE-2022-48560 +Resolves: RHEL-16702 + +* Thu Oct 12 2023 Lumír Balhar - 2.7.18-16 +- Fix for CVE-2022-48565 +Resolves: RHEL-7088 + * Wed Sep 27 2023 Charalampos Stratakis - 2.7.18-15 - Security fix for CVE-2023-40217 Resolves: RHEL-9621