[xml/sgml-commit] r1240 - in /packages/libxml2: ./ trunk/debian/changelog trunk/entities.c trunk/include/libxml/parser.h trunk/parser.c trunk/parserInternals.c

glandium at users.alioth.debian.org glandium at users.alioth.debian.org
Sat Sep 13 07:35:42 UTC 2008


Author: glandium
Date: Sat Sep 13 07:35:42 2008
New Revision: 1240

URL: http://svn.debian.org/wsvn/debian-xml-sgml/?sc=1&rev=1240
Log:
 r1352 at jigen:  mh | 2008-08-25 22:07:53 +0200
 * Fix DoS which leads to recursive evaluation of entities.
   Fixes: CVE-2008-3281, without breaking librsvg and others. Closes: #496125.

Modified:
    packages/libxml2/   (props changed)
    packages/libxml2/trunk/debian/changelog
    packages/libxml2/trunk/entities.c
    packages/libxml2/trunk/include/libxml/parser.h
    packages/libxml2/trunk/parser.c
    packages/libxml2/trunk/parserInternals.c

Propchange: packages/libxml2/
------------------------------------------------------------------------------
--- svk:merge (original)
+++ svk:merge Sat Sep 13 07:35:42 2008
@@ -1,2 +1,2 @@
 85a06573-1206-0410-a182-ce9117885d71:/local/libxml2:296
-a066b643-3b0a-0410-a6ba-ed4cca522822:/local/libxml2:1351
+a066b643-3b0a-0410-a6ba-ed4cca522822:/local/libxml2:1352

Modified: packages/libxml2/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/debian-xml-sgml/packages/libxml2/trunk/debian/changelog?rev=1240&op=diff
==============================================================================
--- packages/libxml2/trunk/debian/changelog (original)
+++ packages/libxml2/trunk/debian/changelog Sat Sep 13 07:35:42 2008
@@ -1,3 +1,10 @@
+libxml2 (2.6.32.dfsg-3) unstable; urgency=high
+
+  * Fix DoS which leads to recursive evaluation of entities.
+    Fixes: CVE-2008-3281, without breaking librsvg and others. Closes: #496125.
+
+ -- Mike Hommey <glandium at debian.org>  Mon, 25 Aug 2008 22:01:17 +0200
+
 libxml2 (2.6.32.dfsg-2) unstable; urgency=low
 
    * debian/control:

Modified: packages/libxml2/trunk/entities.c
URL: http://svn.debian.org/wsvn/debian-xml-sgml/packages/libxml2/trunk/entities.c?rev=1240&op=diff
==============================================================================
--- packages/libxml2/trunk/entities.c (original)
+++ packages/libxml2/trunk/entities.c Sat Sep 13 07:35:42 2008
@@ -102,7 +102,7 @@
         dict = entity->doc->dict;
 
 
-    if ((entity->children) && (entity->owner == 1) &&
+    if ((entity->children) && (entity->owner != 0) &&
         (entity == (xmlEntityPtr) entity->children->parent))
         xmlFreeNodeList(entity->children);
     if (dict != NULL) {

Modified: packages/libxml2/trunk/include/libxml/parser.h
URL: http://svn.debian.org/wsvn/debian-xml-sgml/packages/libxml2/trunk/include/libxml/parser.h?rev=1240&op=diff
==============================================================================
--- packages/libxml2/trunk/include/libxml/parser.h (original)
+++ packages/libxml2/trunk/include/libxml/parser.h Sat Sep 13 07:35:42 2008
@@ -297,6 +297,7 @@
      */
     xmlError          lastError;
     xmlParserMode     parseMode;    /* the parser mode */
+    unsigned long    nbentities;    /* number of entities references */
 };
 
 /**

Modified: packages/libxml2/trunk/parser.c
URL: http://svn.debian.org/wsvn/debian-xml-sgml/packages/libxml2/trunk/parser.c?rev=1240&op=diff
==============================================================================
--- packages/libxml2/trunk/parser.c (original)
+++ packages/libxml2/trunk/parser.c Sat Sep 13 07:35:42 2008
@@ -2344,7 +2344,7 @@
 	return(NULL);
     last = str + len;
 
-    if (ctxt->depth > 40) {
+    if ((ctxt->depth > 40) || (ctxt->nbentities >= 500000)) {
 	xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 	return(NULL);
     }
@@ -2382,6 +2382,11 @@
 			"String decoding Entity Reference: %.30s\n",
 			str);
 	    ent = xmlParseStringEntityRef(ctxt, &str);
+	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
+	        goto int_error;
+	    ctxt->nbentities++;
+	    if (ent != NULL)
+	        ctxt->nbentities += ent->owner;
 	    if ((ent != NULL) &&
 		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
 		if (ent->content != NULL) {
@@ -2427,6 +2432,11 @@
 		xmlGenericError(xmlGenericErrorContext,
 			"String decoding PE Reference: %.30s\n", str);
 	    ent = xmlParseStringPEReference(ctxt, &str);
+	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
+	        goto int_error;
+	    ctxt->nbentities++;
+	    if (ent != NULL)
+	        ctxt->nbentities += ent->owner;
 	    if (ent != NULL) {
                 if (ent->content == NULL) {
 		    if (xmlLoadEntityContent(ctxt, ent) < 0) {
@@ -2468,6 +2478,7 @@
     xmlErrMemory(ctxt, NULL);
     if (rep != NULL)
         xmlFree(rep);
+int_error:
     if (buffer != NULL)
         xmlFree(buffer);
     return(NULL);
@@ -3280,6 +3291,9 @@
 		}
 	    } else {
 		ent = xmlParseEntityRef(ctxt);
+		ctxt->nbentities++;
+		if (ent != NULL)
+		    ctxt->nbentities += ent->owner;
 		if ((ent != NULL) &&
 		    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
 		    if (len > buf_size - 10) {
@@ -4566,6 +4580,7 @@
     int isParameter = 0;
     xmlChar *orig = NULL;
     int skipped;
+    unsigned long oldnbent = ctxt->nbentities;
     
     /* GROW; done in the caller */
     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
@@ -4783,6 +4798,11 @@
 		}
 	    }
             if (cur != NULL) {
+	        if ((cur->owner != 0) || (cur->children == NULL)) {
+		    cur->owner = ctxt->nbentities - oldnbent;
+		    if (cur->owner ==  0)
+		        cur->owner = 1;
+		}
 	        if (cur->orig != NULL)
 		    xmlFree(orig);
 		else
@@ -6189,6 +6209,11 @@
 	if (ent == NULL) return;
 	if (!ctxt->wellFormed)
 	    return;
+	ctxt->nbentities++;
+	if (ctxt->nbentities >= 500000) {
+	    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+	    return;
+	}
 	was_checked = ent->checked;
 	if ((ent->name != NULL) && 
 	    (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
@@ -6240,7 +6265,8 @@
 			    (ent->children == NULL)) {
 			    ent->children = list;
 			    ent->last = list;
-			    ent->owner = 1;
+			    if (ent->owner == 0)
+				ent->owner = 1;
 			    list->parent = (xmlNodePtr) ent;
 			} else {
 			    xmlFreeNodeList(list);
@@ -6249,6 +6275,7 @@
 			xmlFreeNodeList(list);
 		    }
 		} else {
+		    unsigned long oldnbent = ctxt->nbentities;
 		    /*
 		     * 4.3.2: An internal general parsed entity is well-formed
 		     * if its replacement text matches the production labeled
@@ -6271,6 +6298,7 @@
 			ret = xmlParseBalancedChunkMemoryInternal(ctxt,
 					   value, user_data, &list);
 			ctxt->depth--;
+
 		    } else if (ent->etype ==
 			       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
 			ctxt->depth++;
@@ -6282,6 +6310,11 @@
 			ret = XML_ERR_ENTITY_PE_INTERNAL;
 			xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
 				     "invalid entity type found\n", NULL);
+		    }
+		    if ((ent->owner != 0) || (ent->children == NULL)) {
+			ent->owner = ctxt->nbentities - oldnbent;
+			if (ent->owner == 0)
+			    ent->owner = 1;
 		    }
 		    if (ret == XML_ERR_ENTITY_LOOP) {
 			xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
@@ -6301,7 +6334,8 @@
 				    (ctxt->parseMode == XML_PARSE_READER)) {
 				    list->parent = (xmlNodePtr) ent;
 				    list = NULL;
-				    ent->owner = 1;
+				    if (ent->owner == 0)
+					ent->owner = 1;
 				} else {
 				    ent->owner = 0;
 				    while (list != NULL) {
@@ -6318,7 +6352,8 @@
 #endif /* LIBXML_LEGACY_ENABLED */
 				}
 			    } else {
-				ent->owner = 1;
+			        if (ent->owner == 0)
+				    ent->owner = 1;
 				while (list != NULL) {
 				    list->parent = (xmlNodePtr) ent;
 				    if (list->next == NULL)
@@ -6393,6 +6428,7 @@
 		}
 		return;
 	    }
+	    ctxt->nbentities += ent->owner;
 	    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
 	        (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
 		/*
@@ -6495,7 +6531,8 @@
 				break;
 			    cur = next;
 			}
-			ent->owner = 1;
+			if (ent->owner == 0)
+			    ent->owner = 1;
 #ifdef LIBXML_LEGACY_ENABLED
 			if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)			      
 			  xmlAddEntityReference(ent, firstChild, nw);
@@ -11480,7 +11517,7 @@
 
     if (ctx == NULL) return(-1);
 
-    if (ctx->depth > 40) {
+    if ((ctx->depth > 40) || (ctx->nbentities >= 500000)) {
 	return(XML_ERR_ENTITY_LOOP);
     }
 
@@ -11681,7 +11718,8 @@
     xmlChar start[4];
     xmlCharEncoding enc;
 
-    if (depth > 40) {
+    if ((depth > 40) ||
+        ((oldctxt != NULL) && (oldctxt->nbentities >= 500000))) {
 	return(XML_ERR_ENTITY_LOOP);
     }
 
@@ -11824,6 +11862,7 @@
     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
     oldctxt->node_seq.length = ctxt->node_seq.length;
     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    oldctxt->nbentities += ctxt->nbentities;
     ctxt->node_seq.maximum = 0;
     ctxt->node_seq.length = 0;
     ctxt->node_seq.buffer = NULL;
@@ -11924,7 +11963,7 @@
     int size;
     xmlParserErrors ret = XML_ERR_OK;
 
-    if (oldctxt->depth > 40) {
+    if ((oldctxt->depth > 40) || (oldctxt->nbentities >= 500000)) {
 	return(XML_ERR_ENTITY_LOOP);
     }
 
@@ -12048,6 +12087,7 @@
         ctxt->myDoc->last = last;
     }
 	
+    oldctxt->nbentities += ctxt->nbentities;
     ctxt->sax = oldsax;
     ctxt->dict = NULL;
     ctxt->attsDefault = NULL;
@@ -13363,6 +13403,7 @@
     ctxt->depth = 0;
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
     ctxt->catalogs = NULL;
+    ctxt->nbentities = 0;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
 
     if (ctxt->attsDefault != NULL) {

Modified: packages/libxml2/trunk/parserInternals.c
URL: http://svn.debian.org/wsvn/debian-xml-sgml/packages/libxml2/trunk/parserInternals.c?rev=1240&op=diff
==============================================================================
--- packages/libxml2/trunk/parserInternals.c (original)
+++ packages/libxml2/trunk/parserInternals.c Sat Sep 13 07:35:42 2008
@@ -1669,6 +1669,7 @@
     ctxt->depth = 0;
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
     ctxt->catalogs = NULL;
+    ctxt->nbentities = 0;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
     return(0);
 }




More information about the debian-xml-sgml-commit mailing list