109 lines
3.9 KiB
Diff
109 lines
3.9 KiB
Diff
From 6f1470a5d6e3e369fe93f52d5760ba7c947f0cd1 Mon Sep 17 00:00:00 2001
|
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
|
Date: Tue, 25 Aug 2020 18:50:45 +0200
|
|
Subject: [PATCH] Hardcode maximum XPath recursion depth
|
|
|
|
Always limit nested functions calls to 5000. This avoids call stack
|
|
overflows with deeply nested expressions.
|
|
|
|
The expression parser produces about 10 nested function calls when
|
|
parsing a subexpression in parentheses, so the effective nesting limit
|
|
is about 500 which should be more than enough.
|
|
|
|
Use a lower limit when fuzzing to account for increased memory usage
|
|
when using sanitizers.
|
|
|
|
Conflict:delete contents of fuzz/xpath.c
|
|
---
|
|
xpath.c | 25 +++++++++++++++++--------
|
|
1 file changed, 17 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/xpath.c b/xpath.c
|
|
index c018d03..2850a1a 100644
|
|
--- a/xpath.c
|
|
+++ b/xpath.c
|
|
@@ -136,6 +136,17 @@
|
|
#define XPATH_MAX_NODESET_LENGTH 10000000
|
|
|
|
/*
|
|
+ * XPATH_MAX_RECRUSION_DEPTH:
|
|
+ * Maximum amount of nested functions calls when parsing or evaluating
|
|
+ * expressions
|
|
+ */
|
|
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
+#define XPATH_MAX_RECURSION_DEPTH 500
|
|
+#else
|
|
+#define XPATH_MAX_RECURSION_DEPTH 5000
|
|
+#endif
|
|
+
|
|
+/*
|
|
* TODO:
|
|
* There are a few spots where some tests are done which depend upon ascii
|
|
* data. These should be enhanced for full UTF8 support (see particularly
|
|
@@ -6118,8 +6129,6 @@ xmlXPathNewContext(xmlDocPtr doc) {
|
|
ret->contextSize = -1;
|
|
ret->proximityPosition = -1;
|
|
|
|
- ret->maxDepth = INT_MAX;
|
|
-
|
|
#ifdef XP_DEFAULT_CACHE_ON
|
|
if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
|
|
xmlXPathFreeContext(ret);
|
|
@@ -10947,7 +10956,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
|
|
xmlXPathContextPtr xpctxt = ctxt->context;
|
|
|
|
if (xpctxt != NULL) {
|
|
- if (xpctxt->depth >= xpctxt->maxDepth)
|
|
+ if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
|
|
/*
|
|
* Parsing a single '(' pushes about 10 functions on the call stack
|
|
@@ -11883,7 +11892,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
|
|
"xmlXPathCompOpEvalPredicate: Expected a predicate\n");
|
|
XP_ERROR(XPATH_INVALID_OPERAND);
|
|
}
|
|
- if (ctxt->context->depth >= ctxt->context->maxDepth)
|
|
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
|
|
ctxt->context->depth += 1;
|
|
xmlXPathCompOpEvalPredicate(ctxt, &comp->steps[op->ch1], set,
|
|
@@ -12599,7 +12608,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
|
|
CHECK_ERROR0;
|
|
if (OP_LIMIT_EXCEEDED(ctxt, 1))
|
|
return(0);
|
|
- if (ctxt->context->depth >= ctxt->context->maxDepth)
|
|
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
|
|
ctxt->context->depth += 1;
|
|
comp = ctxt->comp;
|
|
@@ -12740,7 +12749,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
|
CHECK_ERROR0;
|
|
if (OP_LIMIT_EXCEEDED(ctxt, 1))
|
|
return(0);
|
|
- if (ctxt->context->depth >= ctxt->context->maxDepth)
|
|
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
|
|
ctxt->context->depth += 1;
|
|
comp = ctxt->comp;
|
|
@@ -12958,7 +12967,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|
CHECK_ERROR0;
|
|
if (OP_LIMIT_EXCEEDED(ctxt, 1))
|
|
return(0);
|
|
- if (ctxt->context->depth >= ctxt->context->maxDepth)
|
|
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
|
|
ctxt->context->depth += 1;
|
|
comp = ctxt->comp;
|
|
@@ -14192,7 +14201,7 @@ xmlXPathOptimizeExpression(xmlXPathParserContextPtr pctxt,
|
|
/* Recurse */
|
|
ctxt = pctxt->context;
|
|
if (ctxt != NULL) {
|
|
- if (ctxt->depth >= ctxt->maxDepth)
|
|
+ if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH)
|
|
return;
|
|
ctxt->depth += 1;
|
|
}
|
|
--
|
|
1.8.3.1
|
|
|