~ruther/guix-local

0c83c6bf2669367e81012391b5bc4ab0406ffbf3 — Leo Famulari 9 years ago daa481f
gnu: libxml2: Fix CVE-2016-4658.

* gnu/packages/xml.scm (libxml2)[replacement]: New field.
(libxml2/fixed): New variable.
* gnu/packages/patches/libxml2-CVE-2016-4658.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
3 files changed, 267 insertions(+), 0 deletions(-)

M gnu/local.mk
A gnu/packages/patches/libxml2-CVE-2016-4658.patch
M gnu/packages/xml.scm
M gnu/local.mk => gnu/local.mk +1 -0
@@ 696,6 696,7 @@ dist_patch_DATA =						\
  %D%/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch	\
  %D%/packages/patches/libwmf-CVE-2015-4695.patch		\
  %D%/packages/patches/libwmf-CVE-2015-4696.patch		\
  %D%/packages/patches/libxml2-CVE-2016-4658.patch		\
  %D%/packages/patches/libxslt-generated-ids.patch		\
  %D%/packages/patches/libxslt-CVE-2016-4738.patch		\
  %D%/packages/patches/linux-pam-no-setfsuid.patch		\

A gnu/packages/patches/libxml2-CVE-2016-4658.patch => gnu/packages/patches/libxml2-CVE-2016-4658.patch +257 -0
@@ 0,0 1,257 @@
Fix CVE-2016-4658:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4658

Patch copied from upstream source repository:

https://git.gnome.org/browse/libxml2/commit/?id=c1d1f7121194036608bf555f08d3062a36fd344b

From c1d1f7121194036608bf555f08d3062a36fd344b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 28 Jun 2016 18:34:52 +0200
Subject: [PATCH] Disallow namespace nodes in XPointer ranges

Namespace nodes must be copied to avoid use-after-free errors.
But they don't necessarily have a physical representation in a
document, so simply disallow them in XPointer ranges.

Found with afl-fuzz.

Fixes CVE-2016-4658.
---
 xpointer.c | 149 +++++++++++++++++++++++--------------------------------------
 1 file changed, 56 insertions(+), 93 deletions(-)

diff --git a/xpointer.c b/xpointer.c
index a7b03fbd..694d120e 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -320,6 +320,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
 }
 
 /**
+ * xmlXPtrNewRangeInternal:
+ * @start:  the starting node
+ * @startindex:  the start index
+ * @end:  the ending point
+ * @endindex:  the ending index
+ *
+ * Internal function to create a new xmlXPathObjectPtr of type range
+ *
+ * Returns the newly created object.
+ */
+static xmlXPathObjectPtr
+xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
+                        xmlNodePtr end, int endindex) {
+    xmlXPathObjectPtr ret;
+
+    /*
+     * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
+     * Disallow them for now.
+     */
+    if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
+	return(NULL);
+    if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = startindex;
+    ret->user2 = end;
+    ret->index2 = endindex;
+    return(ret);
+}
+
+/**
  * xmlXPtrNewRange:
  * @start:  the starting node
  * @startindex:  the start index
@@ -344,17 +383,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex,
     if (endindex < 0)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = startindex;
-    ret->user2 = end;
-    ret->index2 = endindex;
+    ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -381,17 +410,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
     if (end->type != XPATH_POINT)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start->user;
-    ret->index = start->index;
-    ret->user2 = end->user;
-    ret->index2 = end->index;
+    ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
+                                  end->index);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -416,17 +436,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
     if (start->type != XPATH_POINT)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start->user;
-    ret->index = start->index;
-    ret->user2 = end;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -453,17 +463,7 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
     if (end->type != XPATH_POINT)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = end->user;
-    ret->index2 = end->index;
+    ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -486,17 +486,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
     if (end == NULL)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = end;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -516,17 +506,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
     if (start == NULL)
 	return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = NULL;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
     return(ret);
 }
 
@@ -541,6 +521,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
  */
 xmlXPathObjectPtr
 xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+    xmlNodePtr endNode;
+    int endIndex;
     xmlXPathObjectPtr ret;
 
     if (start == NULL)
@@ -549,7 +531,12 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
 	return(NULL);
     switch (end->type) {
 	case XPATH_POINT:
+	    endNode = end->user;
+	    endIndex = end->index;
+	    break;
 	case XPATH_RANGE:
+	    endNode = end->user2;
+	    endIndex = end->index2;
 	    break;
 	case XPATH_NODESET:
 	    /*
@@ -557,39 +544,15 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
 	     */
 	    if (end->nodesetval->nodeNr <= 0)
 		return(NULL);
+	    endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+	    endIndex = -1;
 	    break;
 	default:
 	    /* TODO */
 	    return(NULL);
     }
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    switch (end->type) {
-	case XPATH_POINT:
-	    ret->user2 = end->user;
-	    ret->index2 = end->index;
-	    break;
-	case XPATH_RANGE:
-	    ret->user2 = end->user2;
-	    ret->index2 = end->index2;
-	    break;
-	case XPATH_NODESET: {
-	    ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
-	    ret->index2 = -1;
-	    break;
-	}
-	default:
-	    STRANGE
-	    return(NULL);
-    }
+    ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
-- 
2.11.0


M gnu/packages/xml.scm => gnu/packages/xml.scm +9 -0
@@ 74,6 74,7 @@ things the parser might find in the XML document (like start tags).")
(define-public libxml2
  (package
    (name "libxml2")
    (replacement libxml2/fixed)
    (version "2.9.4")
    (source (origin
             (method url-fetch)


@@ 101,6 102,14 @@ things the parser might find in the XML document (like start tags).")
project (but it is usable outside of the Gnome platform).")
    (license license:x11)))

(define libxml2/fixed
  (package
    (inherit libxml2)
    (source
      (origin
        (inherit (package-source libxml2))
        (patches (search-patches "libxml2-CVE-2016-4658.patch"))))))

(define-public python-libxml2
  (package (inherit libxml2)
    (name "python-libxml2")