fix problems detected by oss-fuzz test

This commit is contained in:
Liquor 2020-11-12 10:24:05 +08:00
parent 6a8d7ece3e
commit adec381a8b
4 changed files with 276 additions and 1 deletions

View File

@ -0,0 +1,37 @@
From b215c270fa3b1436314cc56654718bd12182cfec Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
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

View File

@ -0,0 +1,120 @@
From e6ec58ecf7adf73335cfb40f0d5bc673681f766b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
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

View File

@ -0,0 +1,112 @@
From 847a3a1181d59dc49c1b446d646d344d0543af3e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
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

View File

@ -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 <lirui130@huawei.com> - 2.9.10-10
- fix problems detected by oss-fuzz test
* Thu Oct 29 2020 panxiaohe <panxiaohe@huawei.com> - 2.9.10-9
- remove subpackage python2-libxml2