From a1ea60f87424b417e74297b16c8d0ff176e83037 Mon Sep 17 00:00:00 2001 From: rwx403335 Date: Thu, 21 Jul 2022 15:52:11 +0800 Subject: [PATCH] Fix CVE-2022-2309 --- backport-CVE-2022-2309.patch | 92 +++++++++++++++++++ ...und-libxml2-bug-in-affected-versions.patch | 56 +++++++++++ python-lxml.spec | 7 +- 3 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-2309.patch create mode 100644 backport-Work-around-libxml2-bug-in-affected-versions.patch diff --git a/backport-CVE-2022-2309.patch b/backport-CVE-2022-2309.patch new file mode 100644 index 0000000..448fcfc --- /dev/null +++ b/backport-CVE-2022-2309.patch @@ -0,0 +1,92 @@ +From 86368e9cf70a0ad23cccd5ee32de847149af0c6f Mon Sep 17 00:00:00 2001 +From: Stefan Behnel +Date: Fri, 1 Jul 2022 21:06:10 +0200 +Subject: [PATCH] Fix a crash when incorrect parser input occurs together with + usages of iterwalk() on trees generated by the same parser. + +--- + src/lxml/apihelpers.pxi | 7 ++++--- + src/lxml/iterparse.pxi | 11 ++++++----- + src/lxml/tests/test_etree.py | 20 ++++++++++++++++++++ + 3 files changed, 30 insertions(+), 8 deletions(-) + +diff --git a/src/lxml/apihelpers.pxi b/src/lxml/apihelpers.pxi +index c166276..9fae9fb 100644 +--- a/src/lxml/apihelpers.pxi ++++ b/src/lxml/apihelpers.pxi +@@ -246,9 +246,10 @@ cdef dict _build_nsmap(xmlNode* c_node): + while c_node is not NULL and c_node.type == tree.XML_ELEMENT_NODE: + c_ns = c_node.nsDef + while c_ns is not NULL: +- prefix = funicodeOrNone(c_ns.prefix) +- if prefix not in nsmap: +- nsmap[prefix] = funicodeOrNone(c_ns.href) ++ if c_ns.prefix or c_ns.href: ++ prefix = funicodeOrNone(c_ns.prefix) ++ if prefix not in nsmap: ++ nsmap[prefix] = funicodeOrNone(c_ns.href) + c_ns = c_ns.next + c_node = c_node.parent + return nsmap +diff --git a/src/lxml/iterparse.pxi b/src/lxml/iterparse.pxi +index 138c23a..a7299da 100644 +--- a/src/lxml/iterparse.pxi ++++ b/src/lxml/iterparse.pxi +@@ -420,7 +420,7 @@ cdef int _countNsDefs(xmlNode* c_node): + count = 0 + c_ns = c_node.nsDef + while c_ns is not NULL: +- count += 1 ++ count += (c_ns.href is not NULL) + c_ns = c_ns.next + return count + +@@ -431,9 +431,10 @@ cdef int _appendStartNsEvents(xmlNode* c_node, list event_list) except -1: + count = 0 + c_ns = c_node.nsDef + while c_ns is not NULL: +- ns_tuple = (funicode(c_ns.prefix) if c_ns.prefix is not NULL else '', +- funicode(c_ns.href)) +- event_list.append( (u"start-ns", ns_tuple) ) +- count += 1 ++ if c_ns.href: ++ ns_tuple = (funicodeOrEmpty(c_ns.prefix), ++ funicode(c_ns.href)) ++ event_list.append( (u"start-ns", ns_tuple) ) ++ count += 1 + c_ns = c_ns.next + return count +diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py +index e5f0846..285313f 100644 +--- a/src/lxml/tests/test_etree.py ++++ b/src/lxml/tests/test_etree.py +@@ -1460,6 +1460,26 @@ class ETreeOnlyTestCase(HelperTestCase): + [1,2,1,4], + counts) + ++ def test_walk_after_parse_failure(self): ++ # This used to be an issue because libxml2 can leak empty namespaces ++ # between failed parser runs. iterwalk() failed to handle such a tree. ++ try: ++ etree.XML('''''') ++ except etree.XMLSyntaxError: ++ pass ++ else: ++ assert False, "invalid input did not fail to parse" ++ ++ et = etree.XML(''' ''') ++ try: ++ ns = next(etree.iterwalk(et, events=('start-ns',))) ++ except StopIteration: ++ # This would be the expected result, because there was no namespace ++ pass ++ else: ++ # This is a bug in libxml2 ++ assert not ns, repr(ns) ++ + def test_itertext_comment_pi(self): + # https://bugs.launchpad.net/lxml/+bug/1844674 + XML = self.etree.XML +-- +1.8.3.1 + diff --git a/backport-Work-around-libxml2-bug-in-affected-versions.patch b/backport-Work-around-libxml2-bug-in-affected-versions.patch new file mode 100644 index 0000000..5000072 --- /dev/null +++ b/backport-Work-around-libxml2-bug-in-affected-versions.patch @@ -0,0 +1,56 @@ +From c742576c105f40fc8b754fcae56fee4aa35840a3 Mon Sep 17 00:00:00 2001 +From: Stefan Behnel +Date: Tue, 19 Jul 2022 08:25:20 +0200 +Subject: [PATCH] Work around libxml2 bug in affected versions that failed to + reset the namespace count in the parser context. + +See https://gitlab.gnome.org/GNOME/libxml2/-/issues/378 +--- + src/lxml/includes/xmlparser.pxd | 1 + + src/lxml/parser.pxi | 3 +++ + src/lxml/tests/test_etree.py | 3 +-- + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/lxml/includes/xmlparser.pxd b/src/lxml/includes/xmlparser.pxd +index a196e34..45acfc8 100644 +--- a/src/lxml/includes/xmlparser.pxd ++++ b/src/lxml/includes/xmlparser.pxd +@@ -144,6 +144,7 @@ cdef extern from "libxml/parser.h": + void* userData + int* spaceTab + int spaceMax ++ int nsNr + bint html + bint progressive + int inSubset +diff --git a/src/lxml/parser.pxi b/src/lxml/parser.pxi +index f5baf29..f0c8c6b 100644 +--- a/src/lxml/parser.pxi ++++ b/src/lxml/parser.pxi +@@ -569,6 +569,9 @@ cdef class _ParserContext(_ResolverContext): + self._c_ctxt.disableSAX = 0 # work around bug in libxml2 + else: + xmlparser.xmlClearParserCtxt(self._c_ctxt) ++ # work around bug in libxml2 [2.9.10 .. 2.9.14]: ++ # https://gitlab.gnome.org/GNOME/libxml2/-/issues/378 ++ self._c_ctxt.nsNr = 0 + + cdef int prepare(self, bint set_document_loader=True) except -1: + cdef int result +diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py +index 8bf82c0..0339796 100644 +--- a/src/lxml/tests/test_etree.py ++++ b/src/lxml/tests/test_etree.py +@@ -1491,8 +1491,7 @@ class ETreeOnlyTestCase(HelperTestCase): + # This would be the expected result, because there was no namespace + pass + else: +- # This is a bug in libxml2 +- assert not ns, repr(ns) ++ assert False, "Found unexpected namespace '%s'" % ns + + def test_itertext_comment_pi(self): + # https://bugs.launchpad.net/lxml/+bug/1844674 +-- +1.8.3.1 + diff --git a/python-lxml.spec b/python-lxml.spec index 23f4d82..5d2550c 100644 --- a/python-lxml.spec +++ b/python-lxml.spec @@ -7,7 +7,7 @@ The latest release works with all CPython versions from 2.7 to 3.7. Name: python-%{modname} Version: 4.5.2 -Release: 6 +Release: 7 Summary: XML processing library combining libxml2/libxslt with the ElementTree API License: BSD URL: http://lxml.de @@ -19,6 +19,8 @@ Patch6002: backport-CVE-2021-28957.patch Patch6003: backport-0001-CVE-2021-43818.patch Patch6004: backport-0002-CVE-2021-43818.patch Patch6005: backport-Cleaner-cover-some-more-cases-where-scripts-could-sn.patch +Patch6006: backport-CVE-2022-2309.patch +Patch6007: backport-Work-around-libxml2-bug-in-affected-versions.patch BuildRequires: gcc libxml2-devel libxslt-devel @@ -69,6 +71,9 @@ make test3 %doc README.rst src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt %changelog +* Thu Jul 21 2022 renhongxun - 4.5.2-7 +- fix CVE-2022-2309 + * Sat Jan 22 2022 shixuantong - 4.5.2-6 - Cleaner: cover some more cases where scripts could sneak through in specially crafted style content. -- Gitee