CVE-2017-16932 (published 2017-11-23T21:29Z)

parser.c in libxml2 before 2.9.5 does not prevent infinite recursion in parameter entities.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-835
cwe_name: Loop with Unreachable Exit Condition ('Infinite Loop')
description: The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.
extended_description: If the loop can be influenced by an attacker, this weakness could allow attackers to consume excessive resources such as CPU or memory.
         

Fix information:
repo_url: https://github.com/GNOME/libxml2
commit_details: repo_url: https://github.com/GNOME/libxml2
author: Nick Wellnhofer
author_date: 2017-07-25 14:59:49+02:00
msg: 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.
repository: repo_url: https://github.com/GNOME/libxml2
repo_name: GNOME/libxml2
description: Read-only mirror of https://gitlab.gnome.org/GNOME/libxml2
repo_language: C
owner: GNOME
file_changes: filename: parser.c
change_type: ModificationType.MODIFY
diff: @@ -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)
 		return;
 
 	    input = xmlNewEntityInputStream(ctxt, entity);
-	    if (xmlPushInput(ctxt, input) < 0)
+	    if (xmlPushInput(ctxt, input) < 0) {
+                xmlFreeInputStream(input);
 		return;
+            }
 
 	    if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
                 /*

programming_language: C
filename: 759579.xml.err
change_type: ModificationType.ADD
diff: @@ -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;
+           ^

programming_language: Batchfile
filename: 759579.xml.str
change_type: ModificationType.ADD
diff: @@ -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

programming_language: Batchfile
filename: 759579.xml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,11 @@
+<!DOCTYPE doc [
+    <!ENTITY % z '
+        &#37;z; &#37;z; &#37;z; &#37;z; &#37;z;
+        &#37;z; &#37;z; &#37;z; &#37;z; &#37;z;
+        &#37;z; &#37;z; &#37;z; &#37;z; &#37;z;
+        &#37;z; &#37;z; &#37;z; &#37;z; &#37;z;
+        &#37;z; &#37;z; &#37;z; &#37;z; &#37;z;
+    '>
+    %z;
+]>
+<doc/>

programming_language: HTML