public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo-x86 commit in dev-libs/libxml2/files: libxml2-2.9.2-constant-memory.patch libxml2-2.9.2-missing-entities.patch libxml2-2.9.2-timsort.patch libxml2-2.9.2-threads-declarations.patch
@ 2015-04-19 16:09 Alexandre Rostovtsev (tetromino)
  0 siblings, 0 replies; only message in thread
From: Alexandre Rostovtsev (tetromino) @ 2015-04-19 16:09 UTC (permalink / raw
  To: gentoo-commits

tetromino    15/04/19 16:09:17

  Added:                libxml2-2.9.2-constant-memory.patch
                        libxml2-2.9.2-missing-entities.patch
                        libxml2-2.9.2-timsort.patch
                        libxml2-2.9.2-threads-declarations.patch
  Log:
  Add important patches from upstream, including a fix for a DoS vulnerability (CVE-2015-1819, bug #546720, thanks to Agostino Sarubbo).
  
  (Portage version: 2.2.18/cvs/Linux x86_64, signed Manifest commit with key 0x18E5B6F2D8D5EC8D)

Revision  Changes    Path
1.1                  dev-libs/libxml2/files/libxml2-2.9.2-constant-memory.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-constant-memory.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-constant-memory.patch?rev=1.1&content-type=text/plain

Index: libxml2-2.9.2-constant-memory.patch
===================================================================
From 213f1fe0d76d30eaed6e5853057defc43e6df2c9 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Tue, 14 Apr 2015 17:41:48 +0800
Subject: [PATCH] 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.
---
 buf.c                 | 43 ++++++++++++++++++++++++++++++++++++++++++-
 include/libxml/tree.h |  3 ++-
 xmlreader.c           | 20 +++++++++++++++++++-
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/buf.c b/buf.c
index 6efc7b6..07922ff 100644
--- a/buf.c
+++ b/buf.c
@@ -27,6 +27,7 @@
 #include <libxml/tree.h>
 #include <libxml/globals.h>
 #include <libxml/tree.h>
+#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
 #include "buf.h"
 
 #define WITH_BUFFER_COMPAT
@@ -299,7 +300,8 @@ xmlBufSetAllocationScheme(xmlBufPtr buf,
     if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
         (scheme == XML_BUFFER_ALLOC_EXACT) ||
         (scheme == XML_BUFFER_ALLOC_HYBRID) ||
-        (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) {
+        (scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
+	(scheme == XML_BUFFER_ALLOC_BOUNDED)) {
 	buf->alloc = scheme;
         if (buf->buffer)
             buf->buffer->alloc = scheme;
@@ -458,6 +460,18 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
     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)) {
+	    xmlBufMemoryError(buf, "buffer error: text too long\n");
+	    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;
 
@@ -739,6 +753,15 @@ xmlBufResize(xmlBufPtr buf, size_t size)
     CHECK_COMPAT(buf)
 
     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) {
+	    xmlBufMemoryError(buf, "buffer error: text too long\n");
+	    return(0);
+	}
+    }
 
     /* Don't resize if we don't have to */
     if (size < buf->size)
@@ -867,6 +890,15 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
 
     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) {
+		xmlBufMemoryError(buf, "buffer error: text too long\n");
+		return(-1);
+	    }
+	}
         if (!xmlBufResize(buf, needSize)){
 	    xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
@@ -938,6 +970,15 @@ xmlBufAddHead(xmlBufPtr buf, const xmlChar *str, int len) {
     }
     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) {
+		xmlBufMemoryError(buf, "buffer error: text too long\n");
+		return(-1);
+	    }
+	}
         if (!xmlBufResize(buf, needSize)){
 	    xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 2f90717..4a9b3bc 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -76,7 +76,8 @@ typedef enum {
     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_HYBRID	/* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_HYBRID,	/* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
 } xmlBufferAllocationScheme;
 
 /**
diff --git a/xmlreader.c b/xmlreader.c
index f19e123..471e7e2 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -2091,6 +2091,9 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
 		"xmlNewTextReader : malloc failed\n");
 	return(NULL);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(ret->buffer,
+			      XML_BUFFER_ALLOC_BOUNDED);
     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (ret->sax == NULL) {
 	xmlBufFree(ret->buffer);
@@ -3616,6 +3619,7 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
 	    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) &&
@@ -3629,10 +3633,21 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
                                         "xmlTextReaderSetup : malloc failed\n");
                         return (NULL);
                     }
+		    xmlBufSetAllocationScheme(reader->buffer,
+		                              XML_BUFFER_ALLOC_BOUNDED);
                 } else
                     xmlBufEmpty(reader->buffer);
 	        xmlBufGetNodeContent(reader->buffer, node);
-		return(xmlBufContent(reader->buffer));
+		ret = xmlBufContent(reader->buffer);
+		if (ret == NULL) {
+		    /* error on the buffer best to reallocate */
+		    xmlBufFree(reader->buffer);
+		    reader->buffer = xmlBufCreateSize(100);
+		    xmlBufSetAllocationScheme(reader->buffer,
+		                              XML_BUFFER_ALLOC_BOUNDED);
+		    ret = BAD_CAST "";
+		}
+		return(ret);
 	    }
 	    break;
 	}
@@ -5131,6 +5146,9 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
                         "xmlTextReaderSetup : malloc failed\n");
         return (-1);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(reader->buffer,
+			      XML_BUFFER_ALLOC_BOUNDED);
     if (reader->sax == NULL)
 	reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (reader->sax == NULL) {
-- 
2.3.5




1.1                  dev-libs/libxml2/files/libxml2-2.9.2-missing-entities.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-missing-entities.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-missing-entities.patch?rev=1.1&content-type=text/plain

Index: libxml2-2.9.2-missing-entities.patch
===================================================================
From 72a46a519ce7326d9a00f0b6a7f2a8e958cd1675 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Thu, 23 Oct 2014 11:35:36 +0800
Subject: [PATCH] Fix missing entities after CVE-2014-3660 fix

For https://bugzilla.gnome.org/show_bug.cgi?id=738805

The fix for CVE-2014-3660 introduced a regression in some case
where entity substitution is required and the entity is used
first in anotther entity referenced from an attribute value
---
 parser.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/parser.c b/parser.c
index 67c9dfd..a8d1b67 100644
--- a/parser.c
+++ b/parser.c
@@ -7235,7 +7235,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
      * far more secure as the parser will only process data coming from
      * the document entity by default.
      */
-    if ((ent->checked == 0) &&
+    if (((ent->checked == 0) ||
+         ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
 	unsigned long oldnbent = ctxt->nbentities;
-- 
2.3.5




1.1                  dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch?rev=1.1&content-type=text/plain

Index: libxml2-2.9.2-timsort.patch
===================================================================
From 9b987f8c98763ee569bde90b5268b43474ca106c Mon Sep 17 00:00:00 2001
From: Christopher Swenson <chris@caswenson.com>
Date: Fri, 27 Feb 2015 14:55:49 +0800
Subject: [PATCH] Fix timsort invariant loop re: Envisage article

See http://envisage-project.eu/proving-android-java-and-python-sorting-algorithm-is-broken-and-how-to-fix-it/

We use a "runLen" array of size 128, so it should be nearly impossible
to have our implementation overflow.

But in any case, the fix is relatively simple -- checking two extra
conditions in the invariant calculation.

I also took this opportunity to remove some redundancy in the
left/right merge logic in the invariant loop.
---
 timsort.h | 74 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 39 insertions(+), 35 deletions(-)

diff --git a/timsort.h b/timsort.h
index efa3aab..795f272 100644
--- a/timsort.h
+++ b/timsort.h
@@ -392,62 +392,66 @@ static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const in
 
 static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size)
 {
-  while (1)
-  {
-    int64_t A, B, C;
+  while (1) {
+    int64_t A, B, C, D;
+    int ABC, BCD, BD, CD;
+
     /* if the stack only has one thing on it, we are done with the collapse */
-    if (stack_curr <= 1) break;
+    if (stack_curr <= 1) {
+      break;
+    }
+
     /* if this is the last merge, just do it */
-    if ((stack_curr == 2) &&
-        (stack[0].length + stack[1].length == (int64_t) size))
-    {
+    if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
     }
     /* check if the invariant is off for a stack of 2 elements */
-    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length))
-    {
+    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
-    }
-    else if (stack_curr == 2)
+    } else if (stack_curr == 2) {
       break;
+    }
 
-    A = stack[stack_curr - 3].length;
-    B = stack[stack_curr - 2].length;
-    C = stack[stack_curr - 1].length;
+    B = stack[stack_curr - 3].length;
+    C = stack[stack_curr - 2].length;
+    D = stack[stack_curr - 1].length;
 
-    /* check first invariant */
-    if (A <= B + C)
-    {
-      if (A < C)
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
-        stack[stack_curr - 3].length += stack[stack_curr - 2].length;
-        stack[stack_curr - 2] = stack[stack_curr - 1];
-        stack_curr--;
-      }
-      else
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr, store);
-        stack[stack_curr - 2].length += stack[stack_curr - 1].length;
-        stack_curr--;
-      }
+    if (stack_curr >= 4) {
+      A = stack[stack_curr - 4].length;
+      ABC = (A <= B + C);
+    } else {
+      ABC = 0;
     }
-    /* check second invariant */
-    else if (B <= C)
-    {
+
+    BCD = (B <= C + D) || ABC;
+    CD = (C <= D);
+    BD = (B < D);
+
+    /* Both invariants are good */
+    if (!BCD && !CD) {
+      break;
+    }
+
+    /* left merge */
+    if (BCD && !CD) {
+      TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
+      stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+      stack[stack_curr - 2] = stack[stack_curr - 1];
+      stack_curr--;
+    } else {
+      /* right merge */
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[stack_curr - 2].length += stack[stack_curr - 1].length;
       stack_curr--;
     }
-    else
-      break;
   }
+
   return stack_curr;
 }
 
-- 
2.3.5




1.1                  dev-libs/libxml2/files/libxml2-2.9.2-threads-declarations.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-threads-declarations.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/libxml2/files/libxml2-2.9.2-threads-declarations.patch?rev=1.1&content-type=text/plain

Index: libxml2-2.9.2-threads-declarations.patch
===================================================================
From fff8a6b87e05200a0ad0af6f86c2e859c7de9172 Mon Sep 17 00:00:00 2001
From: Michael Heimpold <mhei@heimpold.de>
Date: Mon, 22 Dec 2014 11:12:12 +0800
Subject: [PATCH] threads: use forward declarations only for glibc

Fixes bug #704908

The declarations of pthread functions, used to generate weak references
to them, fail to suppress macros. Thus, if any pthread function has
been provided as a macro, compiling threads.c will fail.
This breaks on musl libc, which defines pthread_equal as a macro (in
addition to providing the function, as required).

Prevent the declarations for e.g. musl libc by refining the condition.

The idea for this solution was borrowed from the alpine linux guys, see
http://git.alpinelinux.org/cgit/aports/tree/main/libxml2/libxml2-pthread.patch

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
---
 threads.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/threads.c b/threads.c
index 8921204..78006a2 100644
--- a/threads.c
+++ b/threads.c
@@ -47,7 +47,7 @@
 #ifdef HAVE_PTHREAD_H
 
 static int libxml_is_threaded = -1;
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(__GLIBC__)
 #ifdef linux
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
 extern int pthread_once (pthread_once_t *__once_control,
@@ -89,7 +89,7 @@ extern int pthread_cond_signal ()
 	   __attribute((weak));
 #endif
 #endif /* linux */
-#endif /* __GNUC__ */
+#endif /* defined(__GNUC__) && defined(__GLIBC__) */
 #endif /* HAVE_PTHREAD_H */
 
 /*
-- 
2.3.5






^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-04-19 16:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-19 16:09 [gentoo-commits] gentoo-x86 commit in dev-libs/libxml2/files: libxml2-2.9.2-constant-memory.patch libxml2-2.9.2-missing-entities.patch libxml2-2.9.2-timsort.patch libxml2-2.9.2-threads-declarations.patch Alexandre Rostovtsev (tetromino)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox