File libxml2-CVE-2025-9714-8.patch of Package libxml2.41582

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.
---
 fuzz/xpath.c |  3 +--
 xpath.c      | 25 +++++++++++++++++--------
 2 files changed, 18 insertions(+), 10 deletions(-)

Index: libxml2-2.9.7/xpath.c
===================================================================
--- libxml2-2.9.7.orig/xpath.c
+++ libxml2-2.9.7/xpath.c
@@ -126,6 +126,17 @@
 #define XPATH_MAX_STACK_DEPTH 1000000
 
 /*
+ * 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
+
+/*
  * XPATH_DEFAULT_MAX_NODESET_LENGTH:
  * when evaluating an XPath expression nodesets are created and we
  * arbitrary limit the maximum length of those node set. Default value is
@@ -6215,7 +6226,6 @@ xmlXPathNewContext(xmlDocPtr doc) {
     ret->contextSize = -1;
     ret->proximityPosition = -1;
 
-    ret->maxDepth = INT_MAX;
     ret->maxParserDepth = INT_MAX;
 
 #ifdef XP_DEFAULT_CACHE_ON
@@ -11100,7 +11110,7 @@ xmlXPathCompileExpr(xmlXPathParserContex
     xmlXPathContextPtr xpctxt = ctxt->context;
 
     if (xpctxt != NULL) {
-        if (xpctxt->depth >= xpctxt->maxParserDepth)
+        if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH)
             XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
         xpctxt->depth += 1;
     }
@@ -11764,7 +11774,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathPars
 	    * TODO: raise an internal error.
 	    */
 	}
-        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;
 	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
@@ -12834,7 +12844,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserCo
     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;
@@ -12987,7 +12997,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserCon
     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;
@@ -13432,7 +13442,7 @@ xmlXPathCompOpEval(xmlXPathParserContext
     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;
@@ -14977,7 +14987,7 @@ xmlXPathOptimizeExpression(xmlXPathParse
     /* Recurse */
     ctxt = pctxt->context;
     if (ctxt != NULL) {
-        if (ctxt->depth >= ctxt->maxDepth)
+        if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH)
             return;
         ctxt->depth += 1;
     }
openSUSE Build Service is sponsored by