File libxslt-CVE-2025-24855.patch of Package libxslt.38581

From c7c7f1f78dd202a053996fcefe57eb994aec8ef2 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 17 Dec 2024 15:56:21 +0100
Subject: [PATCH] [CVE-2025-24855] Fix use-after-free of XPath context node

There are several places where the XPath context node isn't restored
after modifying it, leading to use-after-free errors with nested XPath
evaluations and dynamically allocated context nodes.

Restore XPath context node in

- xsltNumberFormatGetValue
- xsltEvalXPathPredicate
- xsltEvalXPathStringNs
- xsltComputeSortResultInternal

In some places, the transformation context node was saved and restored
which shouldn't be necessary.

Thanks to Ivan Fratric for the report!

Fixes #128.
---
 libxslt/numbers.c   | 5 +++++
 libxslt/templates.c | 9 ++++++---
 libxslt/xsltutils.c | 4 ++--
 3 files changed, 13 insertions(+), 5 deletions(-)

Index: libxslt-1.1.28/libxslt/numbers.c
===================================================================
--- libxslt-1.1.28.orig/libxslt/numbers.c
+++ libxslt-1.1.28/libxslt/numbers.c
@@ -684,9 +684,12 @@ xsltNumberFormatGetValue(xmlXPathContext
     int amount = 0;
     xmlBufferPtr pattern;
     xmlXPathObjectPtr obj;
+    xmlNodePtr oldNode;
 
     pattern = xmlBufferCreate();
     if (pattern != NULL) {
+        oldNode = context->node;
+
 	xmlBufferCCat(pattern, "number(");
 	xmlBufferCat(pattern, value);
 	xmlBufferCCat(pattern, ")");
@@ -699,6 +702,8 @@ xsltNumberFormatGetValue(xmlXPathContext
 	    xmlXPathFreeObject(obj);
 	}
 	xmlBufferFree(pattern);
+
+        context->node = oldNode;
     }
     return amount;
 }
Index: libxslt-1.1.28/libxslt/templates.c
===================================================================
--- libxslt-1.1.28.orig/libxslt/templates.c
+++ libxslt-1.1.28/libxslt/templates.c
@@ -61,8 +61,10 @@ xsltEvalXPathPredicate(xsltTransformCont
     int oldNsNr;
     xmlNsPtr *oldNamespaces;
     xmlNodePtr oldInst;
+    xmlNodePtr oldNode;
     int oldProximityPosition, oldContextSize;
 
+    oldNode = ctxt->xpathCtxt->node;
     oldContextSize = ctxt->xpathCtxt->contextSize;
     oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
     oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -90,8 +92,9 @@ xsltEvalXPathPredicate(xsltTransformCont
 	ctxt->state = XSLT_STATE_STOPPED;
 	ret = 0;
     }
-    ctxt->xpathCtxt->nsNr = oldNsNr;
 
+    ctxt->xpathCtxt->node = oldNode;
+    ctxt->xpathCtxt->nsNr = oldNsNr;
     ctxt->xpathCtxt->namespaces = oldNamespaces;
     ctxt->inst = oldInst;
     ctxt->xpathCtxt->contextSize = oldContextSize;
@@ -125,7 +128,7 @@ xsltEvalXPathStringNs(xsltTransformConte
     xmlNsPtr *oldNamespaces;
 
     oldInst = ctxt->inst;
-    oldNode = ctxt->node;
+    oldNode = ctxt->xpathCtxt->node;
     oldPos = ctxt->xpathCtxt->proximityPosition;
     oldSize = ctxt->xpathCtxt->contextSize;
     oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -155,7 +158,7 @@ xsltEvalXPathStringNs(xsltTransformConte
 	 "xsltEvalXPathString: returns %s\n", ret));
 #endif
     ctxt->inst = oldInst;
-    ctxt->node = oldNode;
+    ctxt->xpathCtxt->node = oldNode;
     ctxt->xpathCtxt->contextSize = oldSize;
     ctxt->xpathCtxt->proximityPosition = oldPos;
     ctxt->xpathCtxt->nsNr = oldNsNr;
Index: libxslt-1.1.28/libxslt/xsltutils.c
===================================================================
--- libxslt-1.1.28.orig/libxslt/xsltutils.c
+++ libxslt-1.1.28/libxslt/xsltutils.c
@@ -1008,8 +1008,8 @@ xsltComputeSortResult(xsltTransformConte
 	return(NULL);
     }
 
-    oldNode = ctxt->node;
     oldInst = ctxt->inst;
+    oldNode = ctxt->xpathCtxt->node;
     oldPos = ctxt->xpathCtxt->proximityPosition;
     oldSize = ctxt->xpathCtxt->contextSize;
     oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -1071,8 +1071,8 @@ xsltComputeSortResult(xsltTransformConte
 	    results[i] = NULL;
 	}
     }
-    ctxt->node = oldNode;
     ctxt->inst = oldInst;
+    ctxt->xpathCtxt->node = oldNode;
     ctxt->xpathCtxt->contextSize = oldSize;
     ctxt->xpathCtxt->proximityPosition = oldPos;
     ctxt->xpathCtxt->nsNr = oldNsNr;
openSUSE Build Service is sponsored by