File: 0013-CVE-2025-24855-Fix-use-after-free-of-XPath-context-n.patch

package info (click to toggle)
libxslt 1.1.35-1.2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 29,188 kB
  • sloc: xml: 75,620; ansic: 34,684; sh: 4,249; makefile: 3,128; python: 3,060; javascript: 429; perl: 34
file content (133 lines) | stat: -rw-r--r-- 4,516 bytes parent folder | download
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
--- 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 f08b9bda418f..1c8d96e26e95 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 0e9dc62f5fc3..a20da9618228 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;
-- 
2.47.2