1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 17 Dec 2024 15:56:21 +0100
Subject: [CVE-2025-24855] Fix use-after-free of XPath context node
Origin: https://gitlab.gnome.org/GNOME/libxslt/-/commit/c7c7f1f78dd202a053996fcefe57eb994aec8ef2
Bug-Debian: https://bugs.debian.org/1100566
Bug: https://gitlab.gnome.org/GNOME/libxslt/-/issues/128
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-24855
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 0e1fa1368413..741124d1a7cf 100644
@@ -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 f08b9bda418f..1c8d96e26e95 100644
@@ -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 0e9dc62f5fc3..a20da9618228 100644
@@ -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;
--
2.47.2
|