From 899a5d9f0ed13b8e32449a08a361e0de127dd961 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Tue, 25 Jul 2017 14:59:49 +0200 Subject: [PATCH] Detect infinite recursion in parameter entities When expanding a parameter entity in a DTD, infinite recursion could lead to an infinite loop or memory exhaustion. Thanks to Wei Lei for the first of many reports. Fixes bug 759579. CVE: CVE-2017-16932 Upstream-Status: Backport [https://github.com/GNOME/libxml2/commit/899a5d9f0ed13b8e32449a08a361e0de127dd961] Signed-off-by: Andreas Wellving --- parser.c | 11 ++++++++++- result/errors/759579.xml | 0 result/errors/759579.xml.err | 6 ++++++ result/errors/759579.xml.str | 7 +++++++ test/errors/759579.xml | 11 +++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 result/errors/759579.xml create mode 100644 result/errors/759579.xml.err create mode 100644 result/errors/759579.xml.str create mode 100644 test/errors/759579.xml diff --git a/parser.c b/parser.c index 6286cad..51452a2 100644 --- a/parser.c +++ b/parser.c @@ -2250,6 +2250,13 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) { xmlGenericError(xmlGenericErrorContext, "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur); } + if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) || + (ctxt->inputNr > 1024)) { + xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); + while (ctxt->inputNr > 1) + xmlFreeInputStream(inputPop(ctxt)); + return(-1); + } ret = inputPush(ctxt, input); if (ctxt->instate == XML_PARSER_EOF) return(-1); @@ -7916,8 +7923,10 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) * c.f. http://www.w3.org/TR/REC-xml#as-PE */ input = xmlNewEntityInputStream(ctxt, entity); - if (xmlPushInput(ctxt, input) < 0) + if (xmlPushInput(ctxt, input) < 0) { + xmlFreeInputStream(input); return; + } if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { diff --git a/result/errors/759579.xml b/result/errors/759579.xml new file mode 100644 index 0000000..e69de29 diff --git a/result/errors/759579.xml.err b/result/errors/759579.xml.err new file mode 100644 index 0000000..288026e --- /dev/null +++ b/result/errors/759579.xml.err @@ -0,0 +1,6 @@ +Entity: line 2: parser error : Detected an entity reference loop + %z; %z; %z; %z; %z; + ^ +Entity: line 2: + %z; %z; %z; %z; %z; + ^ diff --git a/result/errors/759579.xml.str b/result/errors/759579.xml.str new file mode 100644 index 0000000..09408f5 --- /dev/null +++ b/result/errors/759579.xml.str @@ -0,0 +1,7 @@ +Entity: line 2: parser error : Detected an entity reference loop + %z; %z; %z; %z; %z; + ^ +Entity: line 2: + %z; %z; %z; %z; %z; + ^ +./test/errors/759579.xml : failed to parse diff --git a/test/errors/759579.xml b/test/errors/759579.xml new file mode 100644 index 0000000..7fadd70 --- /dev/null +++ b/test/errors/759579.xml @@ -0,0 +1,11 @@ + + %z; +]> + -- 2.7.4