[xml/sgml-pkgs] Bug#783010: Security update of libxml2 in Debian squeeze-lts

Mike Gabriel mike.gabriel at das-netzwerkteam.de
Thu Jun 4 09:42:51 UTC 2015


Control: tags -1 patch

Dear package maintainers, dear LTS team, dear Daniel Veillard (libxml2  
upstream maintainer),

attached is a .debdiff for fixing CVE-related issues #782782 [0a],  
#782985 [0b] and #783010 [0c] in Debian squeeze-lts. The src:package  
format is 1.0, so changes have been applied on top of the previous  
source code tree version. However, I shipped the individual patches  
for better review in debian/patches (with applying them at build-time).

As the backporting/rebasing of the upstream commit for fixing #782782  
has not been so trivial, I'd highly appreciate a patch review from  
someone with more libxml2'ish background.

Furthermore, only #782782 and #783010 have been fixed upstream  
already, the third issue (#782985) has been reported on upstream GNOME  
bugzilla [1] and also a patch has been provided there [2]. However,  
upstream (i.e., Daniel) hasn't taken any action on fixing that issue,  
so far. Thus, Cc:-ing the upstream maintainer of libxml2 (and hoping  
he can give some feedback on this). What are the plans for that  
reported bug. Any feedback you can give at this time?

For the issues #782985 and #783010 the upstream bug reports provide  
some test cases. I could reproduce the tests failing with the  
2.7.8-2+squeeze11 package version in squeeze-lts and reproduce the  
tests passing with my proposal for 2.7.8-2+squeeze12.

However, for #782782 I do not have any idea how to test that issue, or  
rather in what installation/usage scenarios it is possible to see the  
reported DoS issue coming into play.

The packages have been built against squeeze-lts and uploaded to a  
non-Debian .deb archive [3,4] of mine.

Thanks+Greets,
Mike (from the Debian LTS team)

[0a] http://bugs.debian.org/782782
[0b] http://bugs.debian.org/782985
[0c] http://bugs.debian.org/783010
[1] https://bugzilla.gnome.org/show_bug.cgi?id=746048
[2] https://bugzilla.gnome.org/attachment.cgi?id=299127&action=diff
[3] http://packages.it-zukunft-schule.de/debian/pool/main/libx/libxml2/
[4] deb http://packages.it-zukunft-schule.de/debian squeeze main




-- 

DAS-NETZWERKTEAM
mike gabriel, herweg 7, 24357 fleckeby
fon: +49 (1520) 1976 148

GnuPG Key ID 0x25771B31
mail: mike.gabriel at das-netzwerkteam.de, http://das-netzwerkteam.de

freeBusy:
https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xfb
-------------- next part --------------
diff -u libxml2-2.7.8.dfsg/parser.c libxml2-2.7.8.dfsg/parser.c
--- libxml2-2.7.8.dfsg/parser.c
+++ libxml2-2.7.8.dfsg/parser.c
@@ -5472,6 +5472,7 @@
 	if (RAW != '>') {
 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
 	            "xmlParseEntityDecl: entity %s not terminated\n", name);
+	     xmlStopParser(ctxt);
 	} else {
 	    if (input != ctxt->input) {
 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6583,6 +6584,8 @@
 	SKIP_BLANKS;
 	if (RAW != '[') {
 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	    xmlStopParser(ctxt);
+	    return;
 	} else {
 	    if (ctxt->input->id != id) {
 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6643,6 +6646,8 @@
 	SKIP_BLANKS;
 	if (RAW != '[') {
 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	    xmlStopParser(ctxt);
+	    return;
 	} else {
 	    if (ctxt->input->id != id) {
 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6698,6 +6703,8 @@
 
     } else {
 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+	xmlStopParser(ctxt);
+	return;
     }
 
     if (RAW == 0)
diff -u libxml2-2.7.8.dfsg/debian/rules libxml2-2.7.8.dfsg/debian/rules
--- libxml2-2.7.8.dfsg/debian/rules
+++ libxml2-2.7.8.dfsg/debian/rules
@@ -50,10 +50,10 @@
 override_dh_auto_clean:
 	rm -rf build debian/tmp-dbg
 
-	-test -r /usr/share/misc/config.sub && \
-	cp -f /usr/share/misc/config.sub config.sub
-	-test -r /usr/share/misc/config.guess && \
-	cp -f /usr/share/misc/config.guess config.guess
+#	-test -r /usr/share/misc/config.sub && \
+#	cp -f /usr/share/misc/config.sub config.sub
+#	-test -r /usr/share/misc/config.guess && \
+#	cp -f /usr/share/misc/config.guess config.guess
 
 override_dh_auto_install: $(TARGETS:%=install-%)
 
diff -u libxml2-2.7.8.dfsg/debian/changelog libxml2-2.7.8.dfsg/debian/changelog
--- libxml2-2.7.8.dfsg/debian/changelog
+++ libxml2-2.7.8.dfsg/debian/changelog
@@ -1,3 +1,18 @@
+libxml2 (2.7.8.dfsg-2+squeeze12) squeeze-lts; urgency=medium
+
+  * Non-maintainer upload by the Debian LTS team.
+  * debian/patches:
+    + Fix CVE-2015-1819:  Enforce the reader to run in constant memory.
+      (Closes: #782782).
+    + Fix out-of-bounds memory access when parsing an unclosed HTML comment.
+      (Closes: #782985).
+    + Fix out-of-bound memory access during read operations. (Closes: #783010).
+  * debian/rules:
+    + Disable updating of config.sub and config.guess during
+      override_dh_auto_clean to avoid .debdiff pollution.
+
+ -- Mike Gabriel <sunweaver at debian.org>  Fri, 29 May 2015 13:37:58 +0200
+
 libxml2 (2.7.8.dfsg-2+squeeze11) squeeze-lts; urgency=high
 
   * Non-maintainer upload by the Squeeze LTS Team.
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/HTMLparser.c
+++ libxml2-2.7.8.dfsg/HTMLparser.c
@@ -3194,13 +3194,20 @@
 	ctxt->instate = state;
 	return;
     }
+    if ((ctxt->input->end - ctxt->input->cur) < 3) {
+        ctxt->instate = XML_PARSER_EOF;
+        htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+                     "Comment not terminated\n", NULL, NULL);
+        xmlFree(buf);
+        return;
+    }
     q = CUR_CHAR(ql);
     NEXTL(ql);
     r = CUR_CHAR(rl);
     NEXTL(rl);
     cur = CUR_CHAR(l);
     len = 0;
-    while (IS_CHAR(cur) &&
+    while (((ctxt->input->end - ctxt->input->cur) > 0) && IS_CHAR(cur) &&
            ((cur != '>') ||
 	    (r != '-') || (q != '-'))) {
 	if (len + 5 >= size) {
@@ -3230,7 +3237,7 @@
 	}
     }
     buf[len] = 0;
-    if (!IS_CHAR(cur)) {
+    if (!(ctxt->input->end - ctxt->input->cur) || !IS_CHAR(cur)) {
 	htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
 	             "Comment not terminated \n<!--%.50s\n", buf, NULL);
 	xmlFree(buf);
@@ -3990,6 +3997,7 @@
     depth = ctxt->nameNr;
     while (1) {
 	long cons = ctxt->nbChars;
+	long rem = ctxt->input->end - ctxt->input->cur;
 
         GROW;
 
@@ -4055,7 +4063,7 @@
 	    /*
 	     * Sometimes DOCTYPE arrives in the middle of the document
 	     */
-	    if ((CUR == '<') && (NXT(1) == '!') &&
+	    if ((rem >= 9) && (CUR == '<') && (NXT(1) == '!') &&
 		(UPP(2) == 'D') && (UPP(3) == 'O') &&
 		(UPP(4) == 'C') && (UPP(5) == 'T') &&
 		(UPP(6) == 'Y') && (UPP(7) == 'P') &&
@@ -4069,7 +4077,7 @@
 	    /*
 	     * First case :  a comment
 	     */
-	    if ((CUR == '<') && (NXT(1) == '!') &&
+	    if ((rem >= 4) && (CUR == '<') && (NXT(1) == '!') &&
 		(NXT(2) == '-') && (NXT(3) == '-')) {
 		htmlParseComment(ctxt);
 	    }
@@ -4077,14 +4085,14 @@
 	    /*
 	     * Second case : a Processing Instruction.
 	     */
-	    else if ((CUR == '<') && (NXT(1) == '?')) {
+	    else if ((rem >= 2) && (CUR == '<') && (NXT(1) == '?')) {
 		htmlParsePI(ctxt);
 	    }
 
 	    /*
 	     * Third case :  a sub-element.
 	     */
-	    else if (CUR == '<') {
+	    else if ((rem >= 1 ) && (CUR == '<')) {
 		htmlParseElement(ctxt);
 	    }
 
@@ -4092,7 +4100,7 @@
 	     * Fourth case : a reference. If if has not been resolved,
 	     *    parsing returns it's Name, create the node
 	     */
-	    else if (CUR == '&') {
+	    else if ((rem >= 1) && (CUR == '&')) {
 		htmlParseReference(ctxt);
 	    }
 
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/debian/patches/0001_CVE-2015-1819.patch
+++ libxml2-2.7.8.dfsg/debian/patches/0001_CVE-2015-1819.patch
@@ -0,0 +1,145 @@
+From 213f1fe0d76d30eaed6e5853057defc43e6df2c9 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 14 Apr 2015 17:41:48 +0800
+Subject: CVE-2015-1819 Enforce the reader to run in constant memory
+
+One of the operation on the reader could resolve entities
+leading to the classic expansion issue. Make sure the
+buffer used for xmlreader operation is bounded.
+Introduce a new allocation type for the buffers for this effect.
+
+v2: rebased against libxml2 (<< 2.9)
+    Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+--- a/include/libxml/tree.h
++++ b/include/libxml/tree.h
+@@ -74,7 +74,9 @@
+     XML_BUFFER_ALLOC_DOUBLEIT,	/* double each time one need to grow */
+     XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
+     XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
+-    XML_BUFFER_ALLOC_IO		/* special allocation scheme used for I/O */
++    XML_BUFFER_ALLOC_IO,	/* special allocation scheme used for I/O */
++    _XML_BUFFER_ALLOC_HYBRID, 	/* DUMMY: exact up to a threshold, and doubleit thereafter */
++    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
+ } xmlBufferAllocationScheme;
+ 
+ /**
+--- a/tree.c
++++ b/tree.c
+@@ -678,11 +678,13 @@
+  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
+  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
+  *                             improves performance
++ * XML_BUFFER_ALLOC_BOUNDED - limit the upper size of the buffer
+  */
+ void
+ xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
+     if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
+-        (scheme == XML_BUFFER_ALLOC_DOUBLEIT))
++        (scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
++        (scheme == XML_BUFFER_ALLOC_BOUNDED))
+ 	xmlBufferAllocScheme = scheme;
+ }
+ 
+@@ -7099,6 +7101,19 @@
+     size = buf->use + len + 100;
+ #endif
+ 
++    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
++	/*
++	 * Used to provide parsing limits
++	 */
++	if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
++	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
++	    xmlTreeErrMemory("buffer error: text too long");
++	    return(0);
++	}
++	if (size >= XML_MAX_TEXT_LENGTH)
++	    size = XML_MAX_TEXT_LENGTH;
++    }
++
+     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
+         size_t start_buf = buf->content - buf->contentIO;
+ 
+@@ -7209,7 +7224,15 @@
+         return(0);
+ 
+     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
+-
++    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
++	/*
++	 * Used to provide parsing limits
++	 */
++	if (size >= XML_MAX_TEXT_LENGTH) {
++	    xmlTreeErrMemory("buffer error: text too long");
++	    return(0);
++	}
++    }
+     /* Don't resize if we don't have to */
+     if (size < buf->size)
+         return 1;
+@@ -7388,6 +7411,15 @@
+     }
+     needSize = buf->use + len + 2;
+     if (needSize > buf->size){
++	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
++	    /*
++	     * Used to provide parsing limits
++	     */
++	    if (needSize >= XML_MAX_TEXT_LENGTH) {
++		    xmlTreeErrMemory("buffer error: text too long");
++		    return(-1);
++	    }
++	}
+         if (!xmlBufferResize(buf, needSize)){
+ 	    xmlTreeErrMemory("growing buffer");
+             return XML_ERR_NO_MEMORY;
+--- a/xmlreader.c
++++ b/xmlreader.c
+@@ -2062,6 +2062,8 @@
+ 		"xmlNewTextReader : malloc failed\n");
+ 	return(NULL);
+     }
++    /* no operation on a reader should require a huge buffer */
++    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
+     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
+     if (ret->sax == NULL) {
+ 	xmlBufferFree(ret->buffer);
+@@ -3585,6 +3587,7 @@
+ 	    return(((xmlNsPtr) node)->href);
+         case XML_ATTRIBUTE_NODE:{
+ 	    xmlAttrPtr attr = (xmlAttrPtr) node;
++	    const xmlChar *ret;
+ 
+ 	    if ((attr->children != NULL) &&
+ 	        (attr->children->type == XML_TEXT_NODE) &&
+@@ -3599,8 +3602,20 @@
+ 		    return (NULL);
+ 		}
+ 	        reader->buffer->use = 0;
++		xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
+ 	        xmlNodeBufGetContent(reader->buffer, node);
+-		return(reader->buffer->content);
++		if (!reader->buffer)
++		    ret = NULL;
++		else
++		    ret = reader->buffer->content;
++		if (ret == NULL) {
++		    /* error on the buffer best to reallocate */
++		    xmlBufferFree(reader->buffer);
++		    reader->buffer = xmlBufferCreateSize(100);
++		    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
++		    ret = BAD_CAST "";
++		}
++		return(ret);
+ 	    }
+ 	    break;
+ 	}
+@@ -4977,6 +4992,8 @@
+                         "xmlTextReaderSetup : malloc failed\n");
+         return (-1);
+     }
++    /* no operation on a reader should require a huge buffer */
++    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
+     xmlSAXVersion(reader->sax, 2);
+     reader->startElement = reader->sax->startElement;
+     reader->sax->startElement = xmlTextReaderStartElement;
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/debian/patches/0002_stop-parsing-on-entity-boundary-errors.patch
+++ libxml2-2.7.8.dfsg/debian/patches/0002_stop-parsing-on-entity-boundary-errors.patch
@@ -0,0 +1,24 @@
+From a7dfab7411cbf545f359dd3157e5df1eb0e7ce31 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 23 Feb 2015 11:17:35 +0800
+Subject: Stop parsing on entities boundaries errors
+
+For https://bugzilla.gnome.org/show_bug.cgi?id=744980
+
+There are times, like on unterminated entities that it's preferable to
+stop parsing, even if that means less error reporting. Entities are
+feeding the parser on further processing, and if they are ill defined
+then it's possible to get the parser to bug. Also do the same on
+Conditional Sections if the input is broken, as the structure of
+the document can't be guessed.
+
+--- a/parser.c
++++ b/parser.c
+@@ -5472,6 +5472,7 @@
+ 	if (RAW != '>') {
+ 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
+ 	            "xmlParseEntityDecl: entity %s not terminated\n", name);
++	     xmlStopParser(ctxt);
+ 	} else {
+ 	    if (input != ctxt->input) {
+ 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/debian/patches/0003_cleanup-conditional-section-error-handling.patch
+++ libxml2-2.7.8.dfsg/debian/patches/0003_cleanup-conditional-section-error-handling.patch
@@ -0,0 +1,44 @@
+From 9b8512337d14c8ddf662fcb98b0135f225a1c489 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 23 Feb 2015 11:29:20 +0800
+Subject: Cleanup conditional section error handling
+
+For https://bugzilla.gnome.org/show_bug.cgi?id=744980
+
+The error handling of Conditional Section also need to be
+straightened as the structure of the document can't be
+guessed on a failure there and it's better to stop parsing
+as further errors are likely to be irrelevant.
+
+v2: rebased against v2.7.8 (as found in Debian squeeze)
+    Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/parser.c
++++ b/parser.c
+@@ -6584,6 +6584,8 @@
+ 	SKIP_BLANKS;
+ 	if (RAW != '[') {
+ 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
++	    xmlStopParser(ctxt);
++	    return;
+ 	} else {
+ 	    if (ctxt->input->id != id) {
+ 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+@@ -6644,6 +6646,8 @@
+ 	SKIP_BLANKS;
+ 	if (RAW != '[') {
+ 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
++	    xmlStopParser(ctxt);
++	    return;
+ 	} else {
+ 	    if (ctxt->input->id != id) {
+ 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+@@ -6699,6 +6703,8 @@
+ 
+     } else {
+ 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
++	xmlStopParser(ctxt);
++	return;
+     }
+ 
+     if (RAW == 0)
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/debian/patches/1001_out-of-bounds-memory-access-on-unclosed-HTML-comment.patch
+++ libxml2-2.7.8.dfsg/debian/patches/1001_out-of-bounds-memory-access-on-unclosed-HTML-comment.patch
@@ -0,0 +1,89 @@
+Description: Out-of-bounds memory access when parsing unclosed HTML comments.
+Author: Francois Chagnon
+Origin: https://bugzilla.gnome.org/attachment.cgi?id=299127&action=diff
+
+--- a/HTMLparser.c
++++ b/HTMLparser.c
+@@ -3194,13 +3194,20 @@
+ 	ctxt->instate = state;
+ 	return;
+     }
++    if ((ctxt->input->end - ctxt->input->cur) < 3) {
++        ctxt->instate = XML_PARSER_EOF;
++        htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
++                     "Comment not terminated\n", NULL, NULL);
++        xmlFree(buf);
++        return;
++    }
+     q = CUR_CHAR(ql);
+     NEXTL(ql);
+     r = CUR_CHAR(rl);
+     NEXTL(rl);
+     cur = CUR_CHAR(l);
+     len = 0;
+-    while (IS_CHAR(cur) &&
++    while (((ctxt->input->end - ctxt->input->cur) > 0) && IS_CHAR(cur) &&
+            ((cur != '>') ||
+ 	    (r != '-') || (q != '-'))) {
+ 	if (len + 5 >= size) {
+@@ -3230,7 +3237,7 @@
+ 	}
+     }
+     buf[len] = 0;
+-    if (!IS_CHAR(cur)) {
++    if (!(ctxt->input->end - ctxt->input->cur) || !IS_CHAR(cur)) {
+ 	htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+ 	             "Comment not terminated \n<!--%.50s\n", buf, NULL);
+ 	xmlFree(buf);
+@@ -3990,6 +3997,7 @@
+     depth = ctxt->nameNr;
+     while (1) {
+ 	long cons = ctxt->nbChars;
++	long rem = ctxt->input->end - ctxt->input->cur;
+ 
+         GROW;
+ 
+@@ -4055,7 +4063,7 @@
+ 	    /*
+ 	     * Sometimes DOCTYPE arrives in the middle of the document
+ 	     */
+-	    if ((CUR == '<') && (NXT(1) == '!') &&
++	    if ((rem >= 9) && (CUR == '<') && (NXT(1) == '!') &&
+ 		(UPP(2) == 'D') && (UPP(3) == 'O') &&
+ 		(UPP(4) == 'C') && (UPP(5) == 'T') &&
+ 		(UPP(6) == 'Y') && (UPP(7) == 'P') &&
+@@ -4069,7 +4077,7 @@
+ 	    /*
+ 	     * First case :  a comment
+ 	     */
+-	    if ((CUR == '<') && (NXT(1) == '!') &&
++	    if ((rem >= 4) && (CUR == '<') && (NXT(1) == '!') &&
+ 		(NXT(2) == '-') && (NXT(3) == '-')) {
+ 		htmlParseComment(ctxt);
+ 	    }
+@@ -4077,14 +4085,14 @@
+ 	    /*
+ 	     * Second case : a Processing Instruction.
+ 	     */
+-	    else if ((CUR == '<') && (NXT(1) == '?')) {
++	    else if ((rem >= 2) && (CUR == '<') && (NXT(1) == '?')) {
+ 		htmlParsePI(ctxt);
+ 	    }
+ 
+ 	    /*
+ 	     * Third case :  a sub-element.
+ 	     */
+-	    else if (CUR == '<') {
++	    else if ((rem >= 1 ) && (CUR == '<')) {
+ 		htmlParseElement(ctxt);
+ 	    }
+ 
+@@ -4092,7 +4100,7 @@
+ 	     * Fourth case : a reference. If if has not been resolved,
+ 	     *    parsing returns it's Name, create the node
+ 	     */
+-	    else if (CUR == '&') {
++	    else if ((rem >= 1) && (CUR == '&')) {
+ 		htmlParseReference(ctxt);
+ 	    }
+ 
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/include/libxml/tree.h
+++ libxml2-2.7.8.dfsg/include/libxml/tree.h
@@ -74,7 +74,9 @@
     XML_BUFFER_ALLOC_DOUBLEIT,	/* double each time one need to grow */
     XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
     XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
-    XML_BUFFER_ALLOC_IO		/* special allocation scheme used for I/O */
+    XML_BUFFER_ALLOC_IO,	/* special allocation scheme used for I/O */
+    _XML_BUFFER_ALLOC_HYBRID, 	/* DUMMY: exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
 } xmlBufferAllocationScheme;
 
 /**
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/tree.c
+++ libxml2-2.7.8.dfsg/tree.c
@@ -678,11 +678,13 @@
  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
  *                             improves performance
+ * XML_BUFFER_ALLOC_BOUNDED - limit the upper size of the buffer
  */
 void
 xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
     if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
-        (scheme == XML_BUFFER_ALLOC_DOUBLEIT))
+        (scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
+        (scheme == XML_BUFFER_ALLOC_BOUNDED))
 	xmlBufferAllocScheme = scheme;
 }
 
@@ -7099,6 +7101,19 @@
     size = buf->use + len + 100;
 #endif
 
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+	/*
+	 * Used to provide parsing limits
+	 */
+	if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
+	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
+	    xmlTreeErrMemory("buffer error: text too long");
+	    return(0);
+	}
+	if (size >= XML_MAX_TEXT_LENGTH)
+	    size = XML_MAX_TEXT_LENGTH;
+    }
+
     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
         size_t start_buf = buf->content - buf->contentIO;
 
@@ -7209,7 +7224,15 @@
         return(0);
 
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
-
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+	/*
+	 * Used to provide parsing limits
+	 */
+	if (size >= XML_MAX_TEXT_LENGTH) {
+	    xmlTreeErrMemory("buffer error: text too long");
+	    return(0);
+	}
+    }
     /* Don't resize if we don't have to */
     if (size < buf->size)
         return 1;
@@ -7388,6 +7411,15 @@
     }
     needSize = buf->use + len + 2;
     if (needSize > buf->size){
+	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+	    /*
+	     * Used to provide parsing limits
+	     */
+	    if (needSize >= XML_MAX_TEXT_LENGTH) {
+		    xmlTreeErrMemory("buffer error: text too long");
+		    return(-1);
+	    }
+	}
         if (!xmlBufferResize(buf, needSize)){
 	    xmlTreeErrMemory("growing buffer");
             return XML_ERR_NO_MEMORY;
only in patch2:
unchanged:
--- libxml2-2.7.8.dfsg.orig/xmlreader.c
+++ libxml2-2.7.8.dfsg/xmlreader.c
@@ -2062,6 +2062,8 @@
 		"xmlNewTextReader : malloc failed\n");
 	return(NULL);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (ret->sax == NULL) {
 	xmlBufferFree(ret->buffer);
@@ -3585,6 +3587,7 @@
 	    return(((xmlNsPtr) node)->href);
         case XML_ATTRIBUTE_NODE:{
 	    xmlAttrPtr attr = (xmlAttrPtr) node;
+	    const xmlChar *ret;
 
 	    if ((attr->children != NULL) &&
 	        (attr->children->type == XML_TEXT_NODE) &&
@@ -3599,8 +3602,20 @@
 		    return (NULL);
 		}
 	        reader->buffer->use = 0;
+		xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
 	        xmlNodeBufGetContent(reader->buffer, node);
-		return(reader->buffer->content);
+		if (!reader->buffer)
+		    ret = NULL;
+		else
+		    ret = reader->buffer->content;
+		if (ret == NULL) {
+		    /* error on the buffer best to reallocate */
+		    xmlBufferFree(reader->buffer);
+		    reader->buffer = xmlBufferCreateSize(100);
+		    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
+		    ret = BAD_CAST "";
+		}
+		return(ret);
 	    }
 	    break;
 	}
@@ -4977,6 +4992,8 @@
                         "xmlTextReaderSetup : malloc failed\n");
         return (-1);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_BOUNDED);
     xmlSAXVersion(reader->sax, 2);
     reader->startElement = reader->sax->startElement;
     reader->sax->startElement = xmlTextReaderStartElement;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digitale PGP-Signatur
URL: <http://lists.alioth.debian.org/pipermail/debian-xml-sgml-pkgs/attachments/20150604/b15405d8/attachment-0005.sig>


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