131 lines
4.2 KiB
Diff
131 lines
4.2 KiB
Diff
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(-)
|
|
|
|
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
|
|
index 0e1fa136..741124d1 100644
|
|
--- a/libxslt/numbers.c
|
|
+++ b/libxslt/numbers.c
|
|
@@ -733,9 +733,12 @@ xsltNumberFormatGetValue(xmlXPathContextPtr context,
|
|
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, ")");
|
|
@@ -748,6 +751,8 @@ xsltNumberFormatGetValue(xmlXPathContextPtr context,
|
|
xmlXPathFreeObject(obj);
|
|
}
|
|
xmlBufferFree(pattern);
|
|
+
|
|
+ context->node = oldNode;
|
|
}
|
|
return amount;
|
|
}
|
|
diff --git a/libxslt/templates.c b/libxslt/templates.c
|
|
index f08b9bda..1c8d96e2 100644
|
|
--- a/libxslt/templates.c
|
|
+++ b/libxslt/templates.c
|
|
@@ -61,6 +61,7 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
|
|
int oldNsNr;
|
|
xmlNsPtr *oldNamespaces;
|
|
xmlNodePtr oldInst;
|
|
+ xmlNodePtr oldNode;
|
|
int oldProximityPosition, oldContextSize;
|
|
|
|
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
|
|
@@ -69,6 +70,7 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
|
|
return(0);
|
|
}
|
|
|
|
+ oldNode = ctxt->xpathCtxt->node;
|
|
oldContextSize = ctxt->xpathCtxt->contextSize;
|
|
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
|
|
oldNsNr = ctxt->xpathCtxt->nsNr;
|
|
@@ -96,8 +98,9 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
|
|
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;
|
|
@@ -137,7 +140,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
|
|
}
|
|
|
|
oldInst = ctxt->inst;
|
|
- oldNode = ctxt->node;
|
|
+ oldNode = ctxt->xpathCtxt->node;
|
|
oldPos = ctxt->xpathCtxt->proximityPosition;
|
|
oldSize = ctxt->xpathCtxt->contextSize;
|
|
oldNsNr = ctxt->xpathCtxt->nsNr;
|
|
@@ -167,7 +170,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
|
|
"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;
|
|
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
|
|
index 0e9dc62f..a20da961 100644
|
|
--- a/libxslt/xsltutils.c
|
|
+++ b/libxslt/xsltutils.c
|
|
@@ -1065,8 +1065,8 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
|
|
return(NULL);
|
|
}
|
|
|
|
- oldNode = ctxt->node;
|
|
oldInst = ctxt->inst;
|
|
+ oldNode = ctxt->xpathCtxt->node;
|
|
oldPos = ctxt->xpathCtxt->proximityPosition;
|
|
oldSize = ctxt->xpathCtxt->contextSize;
|
|
oldNsNr = ctxt->xpathCtxt->nsNr;
|
|
@@ -1137,8 +1137,8 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
|
|
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;
|
|
--
|
|
GitLab
|
|
|