diff --git a/Fix-cleanup-of-attributes-in-XML-reader.patch b/Fix-cleanup-of-attributes-in-XML-reader.patch new file mode 100644 index 0000000000000000000000000000000000000000..837e576ff8c8c7e288a3f3c3a45d971584c60204 --- /dev/null +++ b/Fix-cleanup-of-attributes-in-XML-reader.patch @@ -0,0 +1,37 @@ +From b215c270fa3b1436314cc56654718bd12182cfec Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Sun, 13 Sep 2020 12:19:48 +0200 +Subject: [PATCH] Fix cleanup of attributes in XML reader + +xml:id creates ID attributes even in documents without a DTD, so the +check in xmlTextReaderFreeProp must be changed to avoid use after free. + +Found by OSS-Fuzz. +--- + xmlreader.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xmlreader.c b/xmlreader.c +index a9b9ef93..01adf74f 100644 +--- a/xmlreader.c ++++ b/xmlreader.c +@@ -359,12 +359,12 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) { + xmlDeregisterNodeDefaultValue((xmlNodePtr) cur); + + /* Check for ID removal -> leading to invalid references ! */ +- if ((cur->parent != NULL) && (cur->parent->doc != NULL) && +- ((cur->parent->doc->intSubset != NULL) || +- (cur->parent->doc->extSubset != NULL))) { ++ if ((cur->parent != NULL) && (cur->parent->doc != NULL)) { + if (xmlIsID(cur->parent->doc, cur->parent, cur)) + xmlTextReaderRemoveID(cur->parent->doc, cur); +- if (xmlIsRef(cur->parent->doc, cur->parent, cur)) ++ if (((cur->parent->doc->intSubset != NULL) || ++ (cur->parent->doc->extSubset != NULL)) && ++ (xmlIsRef(cur->parent->doc, cur->parent, cur))) + xmlTextReaderRemoveRef(cur->parent->doc, cur); + } + if (cur->children != NULL) +-- +2.27.0 + diff --git a/Fix-null-deref-in-XPointer-expression-error-path.patch b/Fix-null-deref-in-XPointer-expression-error-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..673ae11a021fd7cfa98d7d65712aa1556ad2d871 --- /dev/null +++ b/Fix-null-deref-in-XPointer-expression-error-path.patch @@ -0,0 +1,120 @@ +From e6ec58ecf7adf73335cfb40f0d5bc673681f766b Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Mon, 21 Sep 2020 12:49:36 +0200 +Subject: [PATCH] Fix null deref in XPointer expression error path + +Make sure that the filter functions introduced with commit c2f4da1a +return node-sets without NULL pointers also in the error case. + +Found by OSS-Fuzz. +--- + xpath.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/xpath.c b/xpath.c +index 311997fe..6ee7e57e 100644 +--- a/xpath.c ++++ b/xpath.c +@@ -11677,11 +11677,11 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, + res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1); + + if (ctxt->error != XPATH_EXPRESSION_OK) +- goto exit; ++ break; + if (res < 0) { + /* Shouldn't happen */ + xmlXPathErr(ctxt, XPATH_EXPR_ERROR); +- goto exit; ++ break; + } + + if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) { +@@ -11700,15 +11700,7 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, + + if (res != 0) { + if (pos == maxPos) { +- /* Clear remaining nodes and exit loop. */ +- if (hasNsNodes) { +- for (i++; i < set->nodeNr; i++) { +- node = set->nodeTab[i]; +- if ((node != NULL) && +- (node->type == XML_NAMESPACE_DECL)) +- xmlXPathNodeSetFreeNs((xmlNsPtr) node); +- } +- } ++ i += 1; + break; + } + +@@ -11716,6 +11708,15 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, + } + } + ++ /* Free remaining nodes. */ ++ if (hasNsNodes) { ++ for (; i < set->nodeNr; i++) { ++ xmlNodePtr node = set->nodeTab[i]; ++ if ((node != NULL) && (node->type == XML_NAMESPACE_DECL)) ++ xmlXPathNodeSetFreeNs((xmlNsPtr) node); ++ } ++ } ++ + set->nodeNr = j; + + /* If too many elements were removed, shrink table to preserve memory. */ +@@ -11736,7 +11737,6 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, + } + } + +-exit: + xpctxt->node = oldnode; + xpctxt->doc = olddoc; + xpctxt->contextSize = oldcs; +@@ -11801,11 +11801,11 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, + res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1); + + if (ctxt->error != XPATH_EXPRESSION_OK) +- goto exit; ++ break; + if (res < 0) { + /* Shouldn't happen */ + xmlXPathErr(ctxt, XPATH_EXPR_ERROR); +- goto exit; ++ break; + } + + if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) { +@@ -11823,10 +11823,7 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, + + if (res != 0) { + if (pos == maxPos) { +- /* Clear remaining nodes and exit loop. */ +- for (i++; i < locset->locNr; i++) { +- xmlXPathFreeObject(locset->locTab[i]); +- } ++ i += 1; + break; + } + +@@ -11834,6 +11831,10 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, + } + } + ++ /* Free remaining nodes. */ ++ for (; i < locset->locNr; i++) ++ xmlXPathFreeObject(locset->locTab[i]); ++ + locset->locNr = j; + + /* If too many elements were removed, shrink table to preserve memory. */ +@@ -11854,7 +11855,6 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, + } + } + +-exit: + xpctxt->node = oldnode; + xpctxt->doc = olddoc; + xpctxt->contextSize = oldcs; +-- +2.27.0 + diff --git a/Fix-use-after-free-when-XIncluding-text-from-Reader.patch b/Fix-use-after-free-when-XIncluding-text-from-Reader.patch new file mode 100644 index 0000000000000000000000000000000000000000..15c9e878c9b2f044b4f68edcfc49c506f59d1d50 --- /dev/null +++ b/Fix-use-after-free-when-XIncluding-text-from-Reader.patch @@ -0,0 +1,112 @@ +From 847a3a1181d59dc49c1b446d646d344d0543af3e Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Mon, 28 Sep 2020 12:28:29 +0200 +Subject: [PATCH] Fix use-after-free when XIncluding text from Reader + +The XML Reader can free text nodes coming from the XInclude engine +before parsing has finished. Cache a copy of the text string, not the +included node to avoid use after free. + +Found by OSS-Fuzz. +--- + xinclude.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/xinclude.c b/xinclude.c +index f48e0af5..1636caff 100644 +--- a/xinclude.c ++++ b/xinclude.c +@@ -72,7 +72,7 @@ struct _xmlXIncludeCtxt { + + int txtNr; /* number of unparsed documents */ + int txtMax; /* size of unparsed documents tab */ +- xmlNodePtr *txtTab; /* array of unparsed text nodes */ ++ xmlChar * *txtTab; /* array of unparsed text strings */ + xmlURL *txturlTab; /* array of unparsed text URLs */ + + xmlChar * url; /* the current URL processed */ +@@ -393,18 +393,22 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) { + if (ctxt->incTab[i] != NULL) + xmlXIncludeFreeRef(ctxt->incTab[i]); + } ++ if (ctxt->incTab != NULL) ++ xmlFree(ctxt->incTab); ++ if (ctxt->txtTab != NULL) { ++ for (i = 0;i < ctxt->txtNr;i++) { ++ if (ctxt->txtTab[i] != NULL) ++ xmlFree(ctxt->txtTab[i]); ++ } ++ xmlFree(ctxt->txtTab); ++ } + if (ctxt->txturlTab != NULL) { + for (i = 0;i < ctxt->txtNr;i++) { + if (ctxt->txturlTab[i] != NULL) + xmlFree(ctxt->txturlTab[i]); + } +- } +- if (ctxt->incTab != NULL) +- xmlFree(ctxt->incTab); +- if (ctxt->txtTab != NULL) +- xmlFree(ctxt->txtTab); +- if (ctxt->txturlTab != NULL) + xmlFree(ctxt->txturlTab); ++ } + if (ctxt->base != NULL) { + xmlFree(ctxt->base); + } +@@ -764,13 +768,14 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, + * Add a new text node to the list + */ + static void +-xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { ++xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *txt, ++ const xmlURL url) { + #ifdef DEBUG_XINCLUDE + xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url); + #endif + if (ctxt->txtMax == 0) { + ctxt->txtMax = 4; +- ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax * ++ ctxt->txtTab = (xmlChar **) xmlMalloc(ctxt->txtMax * + sizeof(ctxt->txtTab[0])); + if (ctxt->txtTab == NULL) { + xmlXIncludeErrMemory(ctxt, NULL, "processing text"); +@@ -785,7 +790,7 @@ xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { + } + if (ctxt->txtNr >= ctxt->txtMax) { + ctxt->txtMax *= 2; +- ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab, ++ ctxt->txtTab = (xmlChar **) xmlRealloc(ctxt->txtTab, + ctxt->txtMax * sizeof(ctxt->txtTab[0])); + if (ctxt->txtTab == NULL) { + xmlXIncludeErrMemory(ctxt, NULL, "processing text"); +@@ -798,7 +803,7 @@ xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { + return; + } + } +- ctxt->txtTab[ctxt->txtNr] = txt; ++ ctxt->txtTab[ctxt->txtNr] = xmlStrdup(txt); + ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url); + ctxt->txtNr++; + } +@@ -1845,7 +1850,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { + */ + for (i = 0; i < ctxt->txtNr; i++) { + if (xmlStrEqual(URL, ctxt->txturlTab[i])) { +- node = xmlCopyNode(ctxt->txtTab[i], 1); ++ node = xmlNewText(ctxt->txtTab[i]); + goto loaded; + } + } +@@ -1935,7 +1940,7 @@ xinclude_multibyte_fallback: + xmlBufShrink(buf->buffer, len); + } + xmlFreeParserCtxt(pctxt); +- xmlXIncludeAddTxt(ctxt, node, URL); ++ xmlXIncludeAddTxt(ctxt, node->content, URL); + xmlFreeInputStream(inputStream); + + loaded: +-- +2.27.0 + diff --git a/libxml2.spec b/libxml2.spec index ddafdede145c236fccdea2a323518d1d1d4bf984..efd198aae912f167650b0a0f910f6ed2d381337c 100644 --- a/libxml2.spec +++ b/libxml2.spec @@ -1,7 +1,7 @@ Summary: Library providing XML and HTML support Name: libxml2 Version: 2.9.10 -Release: 9 +Release: 10 License: MIT Group: Development/Libraries Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz @@ -53,6 +53,9 @@ Patch43: Fix-XInclude-regression-introduced-with-recent-commi.patch Patch44: Fix-memory-leak-in-xmlXIncludeAddNode-error-paths.patch Patch45: Fix-double-free-in-XML-reader-with-XIncludes.patch Patch46: Limit-size-of-free-lists-in-XML-reader-when-fuzzing.patch +Patch47: Fix-cleanup-of-attributes-in-XML-reader.patch +Patch48: Fix-null-deref-in-XPointer-expression-error-path.patch +Patch49: Fix-use-after-free-when-XIncluding-text-from-Reader.patch BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: python3-devel @@ -213,6 +216,9 @@ rm -fr %{buildroot} %changelog +* Thu Nov 12 2020 Liquor - 2.9.10-10 +- fix problems detected by oss-fuzz test + * Thu Oct 29 2020 panxiaohe - 2.9.10-9 - remove subpackage python2-libxml2