diff options
Diffstat (limited to 'gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch')
-rw-r--r-- | gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch new file mode 100644 index 0000000000..890e9c2284 --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch @@ -0,0 +1,319 @@ +Fix CVE-2017-{9049,9050}: + +https://bugzilla.gnome.org/show_bug.cgi?id=781205 (not yet public) +https://bugzilla.gnome.org/show_bug.cgi?id=781361 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9049 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9050 +http://www.openwall.com/lists/oss-security/2017/05/15/1 +https://security-tracker.debian.org/tracker/CVE-2017-9049 +https://security-tracker.debian.org/tracker/CVE-2017-9050 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=e26630548e7d138d2c560844c43820b6767251e3 + +Changes to 'runtest.c' are removed since they introduce test failure +when applying to libxml2 2.9.4 release tarball. + +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: [PATCH] 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 6fc8ffa9..10e716a5 100644 +--- a/Makefile.am ++++ b/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 df2efa55..a175ac4e 100644 +--- a/parser.c ++++ b/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 00000000..e69de29b +diff --git a/result/errors10/781205.xml.err b/result/errors10/781205.xml.err +new file mode 100644 +index 00000000..da15c3f7 +--- /dev/null ++++ b/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 00000000..e69de29b +diff --git a/result/errors10/781361.xml.err b/result/errors10/781361.xml.err +new file mode 100644 +index 00000000..655f41a2 +--- /dev/null ++++ b/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 00000000..e69de29b +diff --git a/result/valid/766956.xml.err b/result/valid/766956.xml.err +new file mode 100644 +index 00000000..34b1dae6 +--- /dev/null ++++ b/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 00000000..77603462 +--- /dev/null ++++ b/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/test/errors10/781205.xml b/test/errors10/781205.xml +new file mode 100644 +index 00000000..d9e9e839 +--- /dev/null ++++ b/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 00000000..67476bcb +--- /dev/null ++++ b/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 00000000..19a95a0e +--- /dev/null ++++ b/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 00000000..dddde68b +--- /dev/null ++++ b/test/valid/dtds/766956.dtd +@@ -0,0 +1,2 @@ ++<!ENTITY % ent "value"> ++%ä%ent; +-- +2.14.1 + |