diff options
| author | Brian C. Young <bcyoung@google.com> | 2017-04-03 12:46:02 -0700 |
|---|---|---|
| committer | gitbuildkicker <android-build@google.com> | 2017-04-17 16:24:07 -0700 |
| commit | 0eff71008becb7f2c2b4509708da4b79985948bb (patch) | |
| tree | 143c8b6a1bab7e25e0857f4b4f9991bbe0349de6 | |
| parent | 8ea80f29ea5fdf383ee3ae59ce35e55421a339f8 (diff) | |
| download | android_external_libxml2-0eff71008becb7f2c2b4509708da4b79985948bb.tar.gz android_external_libxml2-0eff71008becb7f2c2b4509708da4b79985948bb.tar.bz2 android_external_libxml2-0eff71008becb7f2c2b4509708da4b79985948bb.zip | |
DO NOT MERGE: 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.
Bug: 36554209
Change-Id: I2bd369290a884c432d16796884d48db6285f8502
(cherry picked from commit e875e1cd1fc92fd2daa57826024125cbd0b195c7)
| -rw-r--r-- | test/XPath/xptr/vidbase | 1 | ||||
| -rw-r--r-- | xpath.c | 7 | ||||
| -rw-r--r-- | xpointer.c | 76 |
3 files changed, 13 insertions, 71 deletions
diff --git a/test/XPath/xptr/vidbase b/test/XPath/xptr/vidbase index b1463830..884b1065 100644 --- a/test/XPath/xptr/vidbase +++ b/test/XPath/xptr/vidbase @@ -1,2 +1,3 @@ xpointer(id('chapter1')/p) xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2])) +xpointer(range-to(id('chapter2'))) @@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 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, @@ -1295,8 +1295,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) { ret->here = here; ret->origin = origin; - xmlXPathRegisterFunc(ret, (xmlChar *)"range-to", - xmlXPtrRangeToFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range", xmlXPtrRangeFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside", @@ -2206,76 +2204,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) { * @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); } /** |
