diff options
Diffstat (limited to 'package/libxml2/libxml2-2.7.8-hardening-xpath.patch')
| -rw-r--r-- | package/libxml2/libxml2-2.7.8-hardening-xpath.patch | 224 | 
1 files changed, 224 insertions, 0 deletions
| diff --git a/package/libxml2/libxml2-2.7.8-hardening-xpath.patch b/package/libxml2/libxml2-2.7.8-hardening-xpath.patch new file mode 100644 index 000000000..8e699ec8c --- /dev/null +++ b/package/libxml2/libxml2-2.7.8-hardening-xpath.patch @@ -0,0 +1,224 @@ +From f5048b3e71fc30ad096970b8df6e7af073bae4cb Mon Sep 17 00:00:00 2001 +From: Daniel Veillard <veillard@redhat.com> +Date: Thu, 18 Aug 2011 09:10:13 +0000 +Subject: Hardening of XPath evaluation + +Add a mechanism of frame for XPath evaluation when entering a function +or a scoped evaluation, also fix a potential problem in predicate +evaluation. +--- +diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h +index 1a9e30e..ddd9dd8 100644 +--- a/include/libxml/xpath.h ++++ b/include/libxml/xpath.h +@@ -68,7 +68,8 @@ typedef enum { +     XPATH_UNDEF_PREFIX_ERROR, +     XPATH_ENCODING_ERROR, +     XPATH_INVALID_CHAR_ERROR, +-    XPATH_INVALID_CTXT ++    XPATH_INVALID_CTXT, ++    XPATH_STACK_ERROR + } xmlXPathError; +  + /* +@@ -380,6 +381,8 @@ struct _xmlXPathParserContext { +     xmlXPathCompExprPtr comp;		/* the precompiled expression */ +     int xptr;				/* it this an XPointer expression */ +     xmlNodePtr         ancestor;	/* used for walking preceding axis */ ++ ++    int              valueFrame;        /* used to limit Pop on the stack */ + }; +  + /************************************************************************ +diff --git a/xpath.c b/xpath.c +index b59ac5a..bcee2ea 100644 +--- a/xpath.c ++++ b/xpath.c +@@ -252,6 +252,7 @@ static const char *xmlXPathErrorMessages[] = { +     "Encoding error\n", +     "Char out of XML range\n", +     "Invalid or incomplete context\n", ++    "Stack usage errror\n", +     "?? Unknown error ??\n"	/* Must be last in the list! */ + }; + #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\ +@@ -2398,6 +2399,42 @@ xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) { +  ************************************************************************/ +  + /** ++ * xmlXPathSetFrame: ++ * @ctxt: an XPath parser context ++ * ++ * Set the callee evaluation frame ++ * ++ * Returns the previous frame value to be restored once done ++ */ ++static int ++xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) { ++    int ret; ++ ++    if (ctxt == NULL) ++        return(0); ++    ret = ctxt->valueFrame; ++    ctxt->valueFrame = ctxt->valueNr; ++    return(ret); ++} ++ ++/** ++ * xmlXPathPopFrame: ++ * @ctxt: an XPath parser context ++ * @frame: the previous frame value ++ * ++ * Remove the callee evaluation frame ++ */ ++static void ++xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) { ++    if (ctxt == NULL) ++        return; ++    if (ctxt->valueNr < ctxt->valueFrame) { ++        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); ++    } ++    ctxt->valueFrame = frame; ++} ++ ++/** +  * valuePop: +  * @ctxt: an XPath evaluation context +  * +@@ -2412,6 +2449,12 @@ valuePop(xmlXPathParserContextPtr ctxt) +  +     if ((ctxt == NULL) || (ctxt->valueNr <= 0)) +         return (NULL); ++ ++    if (ctxt->valueNr <= ctxt->valueFrame) { ++        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); ++        return (NULL); ++    } ++ +     ctxt->valueNr--; +     if (ctxt->valueNr > 0) +         ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; +@@ -6154,6 +6197,7 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { +     ret->valueNr = 0; +     ret->valueMax = 10; +     ret->value = NULL; ++    ret->valueFrame = 0; +  +     ret->context = ctxt; +     ret->comp = comp; +@@ -11711,6 +11755,7 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, + 	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; + 	xmlNodePtr oldContextNode, contextNode = NULL; + 	xmlXPathContextPtr xpctxt = ctxt->context; ++        int frame; +  + #ifdef LIBXML_XPTR_ENABLED + 	    /* +@@ -11730,6 +11775,8 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, + 	*/ + 	exprOp = &ctxt->comp->steps[op->ch2]; + 	for (i = 0; i < set->nodeNr; i++) { ++            xmlXPathObjectPtr tmp; ++ + 	    if (set->nodeTab[i] == NULL) + 		continue; +  +@@ -11757,23 +11804,25 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, + 		xmlXPathNodeSetAddUnique(contextObj->nodesetval, + 		    contextNode); +  ++            frame = xmlXPathSetFrame(ctxt); + 	    valuePush(ctxt, contextObj); + 	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); ++            tmp = valuePop(ctxt); ++            xmlXPathPopFrame(ctxt, frame); +  + 	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { +-	        xmlXPathObjectPtr tmp; +-		/* pop the result if any */ +-		tmp = valuePop(ctxt); +-                if (tmp != contextObj) { ++                while (tmp != contextObj) { +                     /* +                      * Free up the result +                      * then pop off contextObj, which will be freed later +                      */ +                     xmlXPathReleaseObject(xpctxt, tmp); +-                    valuePop(ctxt); ++                    tmp = valuePop(ctxt); +                 } + 		goto evaluation_error; + 	    } ++            /* push the result back onto the stack */ ++            valuePush(ctxt, tmp); +  + 	    if (res) + 		pos++; +@@ -13377,7 +13426,9 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) +                 xmlXPathFunction func; +                 const xmlChar *oldFunc, *oldFuncURI; + 		int i; ++                int frame; +  ++                frame = xmlXPathSetFrame(ctxt); +                 if (op->ch1 != -1) +                     total += +                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); +@@ -13385,15 +13436,18 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) + 		    xmlGenericError(xmlGenericErrorContext, + 			    "xmlXPathCompOpEval: parameter error\n"); + 		    ctxt->error = XPATH_INVALID_OPERAND; ++                    xmlXPathPopFrame(ctxt, frame); + 		    return (total); + 		} +-		for (i = 0; i < op->value; i++) ++		for (i = 0; i < op->value; i++) { + 		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { + 			xmlGenericError(xmlGenericErrorContext, + 				"xmlXPathCompOpEval: parameter error\n"); + 			ctxt->error = XPATH_INVALID_OPERAND; ++                        xmlXPathPopFrame(ctxt, frame); + 			return (total); + 		    } ++                } +                 if (op->cache != NULL) +                     XML_CAST_FPTR(func) = op->cache; +                 else { +@@ -13409,6 +13463,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) +                             xmlGenericError(xmlGenericErrorContext, +             "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", +                                     (char *)op->value4, (char *)op->value5); ++                            xmlXPathPopFrame(ctxt, frame); +                             return (total); +                         } +                         func = xmlXPathFunctionLookupNS(ctxt->context, +@@ -13430,6 +13485,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) +                 func(ctxt, op->value); +                 ctxt->context->function = oldFunc; +                 ctxt->context->functionURI = oldFuncURI; ++                xmlXPathPopFrame(ctxt, frame); +                 return (total); +             } +         case XPATH_OP_ARG: +@@ -14333,6 +14389,7 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) + 	ctxt->valueNr = 0; + 	ctxt->valueMax = 10; + 	ctxt->value = NULL; ++        ctxt->valueFrame = 0; +     } + #ifdef XPATH_STREAMING +     if (ctxt->comp->stream) { +diff --git a/xpointer.c b/xpointer.c +index 7a42d02..37afa3a 100644 +--- a/xpointer.c ++++ b/xpointer.c +@@ -1269,6 +1269,7 @@ xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) { + 	ctxt->valueNr = 0; + 	ctxt->valueMax = 10; + 	ctxt->value = NULL; ++	ctxt->valueFrame = 0; +     } +     SKIP_BLANKS; +     if (CUR == '/') { +-- +cgit v0.9.0.2 | 
