void-packages/srcpkgs/libxml2/patches/CVE-2017-9049-CVE-2017-9050.patch
Helmut Pozimski 40a5a0c7fa libxml2: add patches for multiple CVEs
patches from the GNOME libxml2 git repository at https://git.gnome.org/browse/libxml2/ , revisions:

CVE-2016-4658 c1d1f7121194036608bf555f08d3062a36fd344b
CVE-2016-5131 a005199330b86dada19d162cae15ef9bdcb6baa8 and 9ab01a277d71f54d3143c2cf333c5c2e9aaedd9e
CVE-2017-0663 92b9e8c8b3787068565a1820ba575d042f9eec66
CVE-2017-7375 90ccb58242866b0ba3edbef8fe44214a101c2b3e
CVE-2017-7376 5dca9eea1bd4263bfa4d037ab2443de1cd730f7e
CVE-2017-9047 932cc9896ab41475d4aa429c27d9afd175959d74
CVE-2017-9048 932cc9896ab41475d4aa429c27d9afd175959d74
CVE-2017-9049 e26630548e7d138d2c560844c43820b6767251e3
CVE-2017-9050 e26630548e7d138d2c560844c43820b6767251e3
2017-08-24 15:49:50 +02:00

316 lines
10 KiB
Diff

From e26630548e7d138d2c560844c43820b6767251e3 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 5 Jun 2017 15:37:17 +0200
Subject: Fix handling of parameter-entity references
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There were two bugs where parameter-entity references could lead to an
unexpected change of the input buffer in xmlParseNameComplex and
xmlDictLookup being called with an invalid pointer.
Percent sign in DTD Names
=========================
The NEXTL macro used to call xmlParserHandlePEReference. When parsing
"complex" names inside the DTD, this could result in entity expansion
which created a new input buffer. The fix is to simply remove the call
to xmlParserHandlePEReference from the NEXTL macro. This is safe because
no users of the macro require expansion of parameter entities.
- xmlParseNameComplex
- xmlParseNCNameComplex
- xmlParseNmtoken
The percent sign is not allowed in names, which are grammatical tokens.
- xmlParseEntityValue
Parameter-entity references in entity values are expanded but this
happens in a separate step in this function.
- xmlParseSystemLiteral
Parameter-entity references are ignored in the system literal.
- xmlParseAttValueComplex
- xmlParseCharDataComplex
- xmlParseCommentComplex
- xmlParsePI
- xmlParseCDSect
Parameter-entity references are ignored outside the DTD.
- xmlLoadEntityContent
This function is only called from xmlStringLenDecodeEntities and
entities are replaced in a separate step immediately after the function
call.
This bug could also be triggered with an internal subset and double
entity expansion.
This fixes bug 766956 initially reported by Wei Lei and independently by
Chromium's ClusterFuzz, Hanno Böck, and Marco Grassi. Thanks to everyone
involved.
xmlParseNameComplex with XML_PARSE_OLD10
========================================
When parsing Names inside an expanded parameter entity with the
XML_PARSE_OLD10 option, xmlParseNameComplex would call xmlGROW via the
GROW macro if the input buffer was exhausted. At the end of the
parameter entity's replacement text, this function would then call
xmlPopInput which invalidated the input buffer.
There should be no need to invoke GROW in this situation because the
buffer is grown periodically every XML_PARSER_CHUNK_SIZE characters and,
at least for UTF-8, in xmlCurrentChar. This also matches the code path
executed when XML_PARSE_OLD10 is not set.
This fixes bugs 781205 (CVE-2017-9049) and 781361 (CVE-2017-9050).
Thanks to Marcel Böhme and Thuan Pham for the report.
Additional hardening
====================
A separate check was added in xmlParseNameComplex to validate the
buffer size.
---
Makefile.am | 18 ++++++++++++++++++
parser.c | 18 ++++++++++--------
result/errors10/781205.xml | 0
result/errors10/781205.xml.err | 21 +++++++++++++++++++++
result/errors10/781361.xml | 0
result/errors10/781361.xml.err | 13 +++++++++++++
result/valid/766956.xml | 0
result/valid/766956.xml.err | 9 +++++++++
result/valid/766956.xml.err.rdr | 10 ++++++++++
runtest.c | 3 +++
test/errors10/781205.xml | 3 +++
test/errors10/781361.xml | 3 +++
test/valid/766956.xml | 2 ++
test/valid/dtds/766956.dtd | 2 ++
14 files changed, 94 insertions(+), 8 deletions(-)
create mode 100644 result/errors10/781205.xml
create mode 100644 result/errors10/781205.xml.err
create mode 100644 result/errors10/781361.xml
create mode 100644 result/errors10/781361.xml.err
create mode 100644 result/valid/766956.xml
create mode 100644 result/valid/766956.xml.err
create mode 100644 result/valid/766956.xml.err.rdr
create mode 100644 test/errors10/781205.xml
create mode 100644 test/errors10/781361.xml
create mode 100644 test/valid/766956.xml
create mode 100644 test/valid/dtds/766956.dtd
diff --git a/Makefile.am b/Makefile.am
index 6fc8ffa..10e716a 100644
--- Makefile.am
+++ Makefile.am
@@ -427,6 +427,24 @@ Errtests : xmllint$(EXEEXT)
if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
rm result.$$name error.$$name ; \
fi ; fi ; done)
+ @echo "## Error cases regression tests (old 1.0)"
+ -@(for i in $(srcdir)/test/errors10/*.xml ; do \
+ name=`basename $$i`; \
+ if [ ! -d $$i ] ; then \
+ if [ ! -f $(srcdir)/result/errors10/$$name ] ; then \
+ echo New test file $$name ; \
+ $(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i \
+ 2> $(srcdir)/result/errors10/$$name.err \
+ > $(srcdir)/result/errors10/$$name ; \
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \
+ else \
+ log=`$(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i 2> error.$$name > result.$$name ; \
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \
+ diff $(srcdir)/result/errors10/$$name result.$$name ; \
+ diff $(srcdir)/result/errors10/$$name.err error.$$name` ; \
+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
+ rm result.$$name error.$$name ; \
+ fi ; fi ; done)
@echo "## Error cases stream regression tests"
-@(for i in $(srcdir)/test/errors/*.xml ; do \
name=`basename $$i`; \
diff --git a/parser.c b/parser.c
index df2efa5..a175ac4 100644
--- parser.c
+++ parser.c
@@ -2121,7 +2121,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
ctxt->input->cur += l; \
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
} while (0)
#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
@@ -3412,13 +3411,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
len += l;
NEXTL(l);
c = CUR_CHAR(l);
- if (c == 0) {
- count = 0;
- GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
- c = CUR_CHAR(l);
- }
}
}
if ((len > XML_MAX_NAME_LENGTH) &&
@@ -3426,6 +3418,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
return(NULL);
}
+ if (ctxt->input->cur - ctxt->input->base < len) {
+ /*
+ * There were a couple of bugs where PERefs lead to to a change
+ * of the buffer. Check the buffer size to avoid passing an invalid
+ * pointer to xmlDictLookup.
+ */
+ xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+ "unexpected change of input buffer");
+ return (NULL);
+ }
if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
diff --git a/result/errors10/781205.xml b/result/errors10/781205.xml
new file mode 100644
index 0000000..e69de29
diff --git a/result/errors10/781205.xml.err b/result/errors10/781205.xml.err
new file mode 100644
index 0000000..da15c3f
--- /dev/null
+++ result/errors10/781205.xml.err
@@ -0,0 +1,21 @@
+Entity: line 1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+
+ %a;
+ ^
+Entity: line 1:
+<:0000
+^
+Entity: line 1: parser error : DOCTYPE improperly terminated
+ %a;
+ ^
+Entity: line 1:
+<:0000
+^
+namespace error : Failed to parse QName ':0000'
+ %a;
+ ^
+<:0000
+ ^
+./test/errors10/781205.xml:4: parser error : Couldn't find end of Start Tag :0000 line 1
+
+^
diff --git a/result/errors10/781361.xml b/result/errors10/781361.xml
new file mode 100644
index 0000000..e69de29
diff --git a/result/errors10/781361.xml.err b/result/errors10/781361.xml.err
new file mode 100644
index 0000000..655f41a
--- /dev/null
+++ result/errors10/781361.xml.err
@@ -0,0 +1,13 @@
+./test/errors10/781361.xml:4: parser error : xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected
+
+^
+./test/errors10/781361.xml:4: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+
+
+^
+./test/errors10/781361.xml:4: parser error : DOCTYPE improperly terminated
+
+^
+./test/errors10/781361.xml:4: parser error : Start tag expected, '<' not found
+
+^
diff --git a/result/valid/766956.xml b/result/valid/766956.xml
new file mode 100644
index 0000000..e69de29
diff --git a/result/valid/766956.xml.err b/result/valid/766956.xml.err
new file mode 100644
index 0000000..34b1dae
--- /dev/null
+++ result/valid/766956.xml.err
@@ -0,0 +1,9 @@
+test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
+%ä%ent;
+ ^
+Entity: line 1: parser error : Content error in the external subset
+ %ent;
+ ^
+Entity: line 1:
+value
+^
diff --git a/result/valid/766956.xml.err.rdr b/result/valid/766956.xml.err.rdr
new file mode 100644
index 0000000..7760346
--- /dev/null
+++ result/valid/766956.xml.err.rdr
@@ -0,0 +1,10 @@
+test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
+%ä%ent;
+ ^
+Entity: line 1: parser error : Content error in the external subset
+ %ent;
+ ^
+Entity: line 1:
+value
+^
+./test/valid/766956.xml : failed to parse
diff --git a/runtest.c b/runtest.c
index b2ce693..378b38e 100644
--- runtest.c
+++ runtest.c
@@ -4214,6 +4214,9 @@ testDesc testDescriptions[] = {
{ "Error cases regression tests",
errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
0 },
+ { "Error cases regression tests (old 1.0)",
+ errParseTest, "./test/errors10/*.xml", "result/errors10/", "", ".err",
+ XML_PARSE_OLD10 },
#ifdef LIBXML_READER_ENABLED
{ "Error cases stream regression tests",
streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",
diff --git a/test/errors10/781205.xml b/test/errors10/781205.xml
new file mode 100644
index 0000000..d9e9e83
--- /dev/null
+++ test/errors10/781205.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE D [
+ <!ENTITY % a "<:0000">
+ %a;
diff --git a/test/errors10/781361.xml b/test/errors10/781361.xml
new file mode 100644
index 0000000..67476bc
--- /dev/null
+++ test/errors10/781361.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE doc [
+ <!ENTITY % elem "<!ELEMENT e0000000000">
+ %elem;
diff --git a/test/valid/766956.xml b/test/valid/766956.xml
new file mode 100644
index 0000000..19a95a0
--- /dev/null
+++ test/valid/766956.xml
@@ -0,0 +1,2 @@
+<!DOCTYPE test SYSTEM "dtds/766956.dtd">
+<test/>
diff --git a/test/valid/dtds/766956.dtd b/test/valid/dtds/766956.dtd
new file mode 100644
index 0000000..dddde68
--- /dev/null
+++ test/valid/dtds/766956.dtd
@@ -0,0 +1,2 @@
+<!ENTITY % ent "value">
+%ä%ent;
--
cgit v0.12