Fix use after free with validating reader

This commit is contained in:
Yangyang Shen 2020-07-28 09:55:58 +08:00
parent 36c48726be
commit e984b33634
3 changed files with 186 additions and 19 deletions

View File

@ -0,0 +1,91 @@
From 2af3c2a8b974cb5896cd3beb74561ba979de9f34 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 8 Jun 2020 12:49:51 +0200
Subject: [PATCH] Fix use-after-free with validating reader
Just like IDs, IDREF attributes must be removed from the document's
refs table when they're freed by a reader. This bug is often hidden
because xmlAttr structs are reused and strings are stored in a
dictionary unless XML_PARSE_NODICT is specified.
Found by OSS-Fuzz.
---
xmlreader.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/xmlreader.c b/xmlreader.c
index 3fd9aa4c0..6ae6e9229 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -278,6 +278,59 @@ xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
return(0);
}
+/**
+ * xmlTextReaderWalkRemoveRef:
+ * @data: Contents of current link
+ * @user: Value supplied by the user
+ *
+ * Returns 0 to abort the walk or 1 to continue
+ */
+static int
+xmlTextReaderWalkRemoveRef(const void *data, void *user)
+{
+ xmlRefPtr ref = (xmlRefPtr)data;
+ xmlAttrPtr attr = (xmlAttrPtr)user;
+
+ if (ref->attr == attr) { /* Matched: remove and terminate walk */
+ ref->name = xmlStrdup(attr->name);
+ ref->attr = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * xmlTextReaderRemoveRef:
+ * @doc: the document
+ * @attr: the attribute
+ *
+ * Remove the given attribute from the Ref table maintained internally.
+ *
+ * Returns -1 if the lookup failed and 0 otherwise
+ */
+static int
+xmlTextReaderRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
+ xmlListPtr ref_list;
+ xmlRefTablePtr table;
+ xmlChar *ID;
+
+ if (doc == NULL) return(-1);
+ if (attr == NULL) return(-1);
+ table = (xmlRefTablePtr) doc->refs;
+ if (table == NULL)
+ return(-1);
+
+ ID = xmlNodeListGetString(doc, attr->children, 1);
+ if (ID == NULL)
+ return(-1);
+ ref_list = xmlHashLookup(table, ID);
+ xmlFree(ID);
+ if(ref_list == NULL)
+ return (-1);
+ xmlListWalk(ref_list, xmlTextReaderWalkRemoveRef, attr);
+ return(0);
+}
+
/**
* xmlTextReaderFreeProp:
* @reader: the xmlTextReaderPtr used
@@ -304,6 +357,8 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
(cur->parent->doc->extSubset != NULL))) {
if (xmlIsID(cur->parent->doc, cur->parent, cur))
xmlTextReaderRemoveID(cur->parent->doc, cur);
+ if (xmlIsRef(cur->parent->doc, cur->parent, cur))
+ xmlTextReaderRemoveRef(cur->parent->doc, cur);
}
if (cur->children != NULL)
xmlTextReaderFreeNodeList(reader, cur->children);
--
GitLab

View File

@ -0,0 +1,70 @@
From a28f7d8789e63f5e2ac63b42083754cba58f1a0e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 10 Jun 2020 13:41:13 +0200
Subject: [PATCH] Never expand parameter entities in text declaration
When parsing the text declaration of external DTDs or entities, make
sure that parameter entities are not expanded. This also fixes a memory
leak in certain error cases.
The change to xmlSkipBlankChars assumes that the parser state is
maintained correctly when parsing external DTDs or parameter entities,
and might expose bugs in the code that were hidden previously.
Found by OSS-Fuzz.
---
parser.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/parser.c b/parser.c
index 046f1cec3..3559aaaec 100644
--- a/parser.c
+++ b/parser.c
@@ -2156,7 +2156,7 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
* It's Okay to use CUR/NEXT here since all the blanks are on
* the ASCII range.
*/
- if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
+ if (ctxt->instate != XML_PARSER_DTD) {
const xmlChar *cur;
/*
* if we are in the document content, go really fast
@@ -6852,6 +6852,7 @@ void
xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
xmlChar *version;
const xmlChar *encoding;
+ int oldstate;
/*
* We know that '<?xml' is here.
@@ -6863,6 +6864,10 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
return;
}
+ /* Avoid expansion of parameter entities when skipping blanks. */
+ oldstate = ctxt->instate;
+ ctxt->instate = XML_PARSER_START;
+
if (SKIP_BLANKS == 0) {
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
"Space needed after '<?xml'\n");
@@ -6890,6 +6895,7 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
/*
* The XML REC instructs us to stop parsing right here
*/
+ ctxt->instate = oldstate;
return;
}
if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
@@ -6909,6 +6915,8 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
MOVETO_ENDTAG(CUR_PTR);
NEXT;
}
+
+ ctxt->instate = oldstate;
}
/**
--
GitLab

View File

@ -1,29 +1,31 @@
Summary: Library providing XML and HTML support
Name: libxml2
Version: 2.9.10
Release: 2
Release: 3
License: MIT
Group: Development/Libraries
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
Patch0: libxml2-multilib.patch
# upstream patches
Patch6001: backport-Fix-memory-leak-in-xmlSchemaValidateStream.patch
Patch6002: backport-fix-infinite-loop-in-xmlStringLenDecodeEntities.patch
Patch6003: backport-Updated-python-tests-tstLastError.py.patch
Patch0004: Null-pointer-handling-in-catalog-c.patch
Patch0005: Fix-overflow-handling-in-xmlBufBackToBuffer.patch
Patch0006: Fix-memory-leak-in-error-path-of-XPath-expr-parser.patch
Patch0007: Fix-memory-leaks-of-encoding-handlers-in-xmlsave-c.patch
Patch0008: Use-random-seed-in-xmlDictComputeFastKey.patch
Patch0009: Fix-more-memory-leaks-in-error-paths-of-XPath-parser.patch
Patch0010: Fix-freeing-of-nested-documents.patch
Patch0011: Fix-overflow-check-in-xmlNodeDump.patch
Patch0012: Check-for-overflow-when-allocating-two-dimensional-a.patch
Patch0013: Fix-integer-overflow-in-xmlBufferResize.patch
Patch0014: Fix-copying-of-entities-in-xmlParseReference.patch
Patch0015: Copy-some-XMLReader-option-flags-to-parser-context.patch
Patch0016: Merge-code-paths-loading-external-entities.patch
Patch0017: Don-t-load-external-entity-from-xmlSAX2GetEntity.patch
Patch1: backport-Fix-memory-leak-in-xmlSchemaValidateStream.patch
Patch2: backport-fix-infinite-loop-in-xmlStringLenDecodeEntities.patch
Patch3: backport-Updated-python-tests-tstLastError.py.patch
Patch4: Null-pointer-handling-in-catalog-c.patch
Patch5: Fix-overflow-handling-in-xmlBufBackToBuffer.patch
Patch6: Fix-memory-leak-in-error-path-of-XPath-expr-parser.patch
Patch7: Fix-memory-leaks-of-encoding-handlers-in-xmlsave-c.patch
Patch8: Use-random-seed-in-xmlDictComputeFastKey.patch
Patch9: Fix-more-memory-leaks-in-error-paths-of-XPath-parser.patch
Patch10: Fix-freeing-of-nested-documents.patch
Patch11: Fix-overflow-check-in-xmlNodeDump.patch
Patch12: Check-for-overflow-when-allocating-two-dimensional-a.patch
Patch13: Fix-integer-overflow-in-xmlBufferResize.patch
Patch14: Fix-copying-of-entities-in-xmlParseReference.patch
Patch15: Copy-some-XMLReader-option-flags-to-parser-context.patch
Patch16: Merge-code-paths-loading-external-entities.patch
Patch17: Don-t-load-external-entity-from-xmlSAX2GetEntity.patch
Patch18: Fix-use-after-free-with-validating-reader.patch
Patch19: Never-expand-parameter-entities-in-text-declaration.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: python2-devel
@ -215,7 +217,11 @@ rm -fr %{buildroot}
%changelog
* Wed Jun 24 2020 wangchen <wangchen137@huawei.com> - 2.9.10-2
* Tue Jul 28 2020 shenyangyang <shenyangyang4@huawei.com> - 2.9.10-3
- Fix-use-after-free-with-validating-reader and
Never-expand-parameter-entities-in-text-declaration
* Fri Jul 3 2020 wangchen <wangchen137@huawei.com> - 2.9.10-2
- Sync some patches from community
* Fri Apr 24 2020 BruceGW <gyl93216@163.com> - 2.9.10-1