Package: libxml2 / 2.9.4+dfsg1-2.2+deb9u2

0005-Fix-XPointer-paths-beginning-with-range-to.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 9ab01a277d71f54d3143c2cf333c5c2e9aaedd9e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 28 Jun 2016 14:22:23 +0200
Subject: [PATCH] Fix XPointer paths beginning with range-to

The old code would invoke the broken xmlXPtrRangeToFunction. range-to
isn't really a function but a special kind of location step. Remove
this function and always handle range-to in the XPath code.

The old xmlXPtrRangeToFunction could also be abused to trigger a
use-after-free error with the potential for remote code execution.

Found with afl-fuzz.

Fixes CVE-2016-5131.
---
 result/XPath/xptr/vidbase | 13 ++++++++
 test/XPath/xptr/vidbase   |  1 +
 xpath.c                   |  7 ++++-
 xpointer.c                | 76 ++++-------------------------------------------
 4 files changed, 26 insertions(+), 71 deletions(-)

--- a/xpath.c
+++ b/xpath.c
@@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserConte
 		    lc = 1;
 		    break;
 		} else if ((NXT(len) == '(')) {
-		    /* Note Type or Function */
+		    /* Node Type or Function */
 		    if (xmlXPathIsNodeType(name)) {
 #ifdef DEBUG_STEP
 		        xmlGenericError(xmlGenericErrorContext,
 				"PathExpr: Type search\n");
 #endif
 			lc = 1;
+#ifdef LIBXML_XPTR_ENABLED
+                    } else if (ctxt->xptr &&
+                               xmlStrEqual(name, BAD_CAST "range-to")) {
+                        lc = 1;
+#endif
 		    } else {
 #ifdef DEBUG_STEP
 		        xmlGenericError(xmlGenericErrorContext,
--- a/xpointer.c
+++ b/xpointer.c
@@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNode
     ret->here = here;
     ret->origin = origin;
 
-    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
-	                 xmlXPtrRangeToFunction);
     xmlXPathRegisterFunc(ret, (xmlChar *)"range",
 	                 xmlXPtrRangeFunction);
     xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
@@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParse
  * @nargs:  the number of args
  *
  * Implement the range-to() XPointer function
+ *
+ * Obsolete. range-to is not a real function but a special type of location
+ * step which is handled in xpath.c.
  */
 void
-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-    xmlXPathObjectPtr range;
-    const xmlChar *cur;
-    xmlXPathObjectPtr res, obj;
-    xmlXPathObjectPtr tmp;
-    xmlLocationSetPtr newset = NULL;
-    xmlNodeSetPtr oldset;
-    int i;
-
-    if (ctxt == NULL) return;
-    CHECK_ARITY(1);
-    /*
-     * Save the expression pointer since we will have to evaluate
-     * it multiple times. Initialize the new set.
-     */
-    CHECK_TYPE(XPATH_NODESET);
-    obj = valuePop(ctxt);
-    oldset = obj->nodesetval;
-    ctxt->context->node = NULL;
-
-    cur = ctxt->cur;
-    newset = xmlXPtrLocationSetCreate(NULL);
-
-    for (i = 0; i < oldset->nodeNr; i++) {
-	ctxt->cur = cur;
-
-	/*
-	 * Run the evaluation with a node list made of a single item
-	 * in the nodeset.
-	 */
-	ctxt->context->node = oldset->nodeTab[i];
-	tmp = xmlXPathNewNodeSet(ctxt->context->node);
-	valuePush(ctxt, tmp);
-
-	xmlXPathEvalExpr(ctxt);
-	CHECK_ERROR;
-
-	/*
-	 * The result of the evaluation need to be tested to
-	 * decided whether the filter succeeded or not
-	 */
-	res = valuePop(ctxt);
-	range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
-	if (range != NULL) {
-	    xmlXPtrLocationSetAdd(newset, range);
-	}
-
-	/*
-	 * Cleanup
-	 */
-	if (res != NULL)
-	    xmlXPathFreeObject(res);
-	if (ctxt->value == tmp) {
-	    res = valuePop(ctxt);
-	    xmlXPathFreeObject(res);
-	}
-
-	ctxt->context->node = NULL;
-    }
-
-    /*
-     * The result is used as the new evaluation set.
-     */
-    xmlXPathFreeObject(obj);
-    ctxt->context->node = NULL;
-    ctxt->context->contextSize = -1;
-    ctxt->context->proximityPosition = -1;
-    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
+                       int nargs ATTRIBUTE_UNUSED) {
+    XP_ERROR(XPATH_EXPR_ERROR);
 }
 
 /**