• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From e64653c0e7975594e27d7de2ed4be062c1e4ad03 Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Fri, 17 Feb 2023 15:20:33 +0100
4Subject: [PATCH] malloc-fail: Fix leak of xmlRegAtom
5
6Found with libFuzzer, see #344.
7
8Reference:https://github.com/GNOME/libxml2/commit/e64653c0e7975594e27d7de2ed4be062c1e4ad03
9Conflict:NA
10---
11 xmlregexp.c | 81 ++++++++++++++++++++++++++++++++++++-----------------
12 1 file changed, 55 insertions(+), 26 deletions(-)
13
14diff --git a/xmlregexp.c b/xmlregexp.c
15index 8c2ea81..11c684a 100644
16--- a/xmlregexp.c
17+++ b/xmlregexp.c
18@@ -1594,9 +1594,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
19 	 * this is a subexpression handling one should not need to
20 	 * create a new node except for XML_REGEXP_QUANT_RANGE.
21 	 */
22-	if (xmlRegAtomPush(ctxt, atom) < 0) {
23-	    return(-1);
24-	}
25 	if ((to != NULL) && (atom->stop != to) &&
26 	    (atom->quant != XML_REGEXP_QUANT_RANGE)) {
27 	    /*
28@@ -1678,8 +1675,10 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
29 		    copy->max = 0;
30
31 		    if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy)
32-		        < 0)
33+		        < 0) {
34+                        xmlRegFreeAtom(copy);
35 			return(-1);
36+                    }
37 		    inter = ctxt->state;
38 		    counter = xmlRegGetCounter(ctxt);
39 		    ctxt->counters[counter].min = atom->min - 1;
40@@ -1722,6 +1721,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
41 	    default:
42 		break;
43 	}
44+	if (xmlRegAtomPush(ctxt, atom) < 0)
45+	    return(-1);
46 	return(0);
47     }
48     if ((atom->min == 0) && (atom->max == 0) &&
49@@ -1760,9 +1761,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
50 	xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
51 	to = tmp;
52     }
53-    if (xmlRegAtomPush(ctxt, atom) < 0) {
54-	return(-1);
55-    }
56     if ((atom->quant == XML_REGEXP_QUANT_RANGE) &&
57         (atom->min == 0) && (atom->max > 0)) {
58 	nullable = 1;
59@@ -1793,6 +1791,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
60 	default:
61 	    break;
62     }
63+    if (xmlRegAtomPush(ctxt, atom) < 0)
64+	return(-1);
65     return(0);
66 }
67
68@@ -5447,8 +5447,12 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
69 	xmlFAGenerateEpsilonTransition(ctxt, previous, to);
70     } else {
71 	if (xmlFAGenerateTransitions(ctxt, previous,
72-	        (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, ctxt->atom) < 0)
73+	        (CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
74+                ctxt->atom) < 0) {
75+            xmlRegFreeAtom(ctxt->atom);
76+            ctxt->atom = NULL;
77 	    return(-1);
78+        }
79 	previous = ctxt->state;
80 	ctxt->atom = NULL;
81     }
82@@ -5457,8 +5461,11 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
83 	if (ret != 0) {
84 	    if (xmlFAGenerateTransitions(ctxt, previous,
85 	            (CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
86-                    ctxt->atom) < 0)
87-		    return(-1);
88+                    ctxt->atom) < 0) {
89+                xmlRegFreeAtom(ctxt->atom);
90+                ctxt->atom = NULL;
91+                return(-1);
92+            }
93 	    previous = ctxt->state;
94 	    ctxt->atom = NULL;
95 	}
96@@ -5990,6 +5997,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
97 	return(NULL);
98     if ((token2 == NULL) || (*token2 == 0)) {
99 	atom->valuep = xmlStrdup(token);
100+        if (atom->valuep == NULL)
101+            goto error;
102     } else {
103 	int lenn, lenp;
104 	xmlChar *str;
105@@ -5998,10 +6007,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
106 	lenp = strlen((char *) token);
107
108 	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
109-	if (str == NULL) {
110-	    xmlRegFreeAtom(atom);
111-	    return(NULL);
112-	}
113+	if (str == NULL)
114+	    goto error;
115 	memcpy(&str[0], token, lenp);
116 	str[lenp] = '|';
117 	memcpy(&str[lenp + 1], token2, lenn);
118@@ -6027,10 +6034,11 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
119     if (to == NULL) {
120 	to = xmlRegStatePush(am);
121         if (to == NULL)
122-            return(NULL);
123+            goto error;
124     }
125     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
126-    xmlRegAtomPush(am, atom);
127+    if (xmlRegAtomPush(am, atom) < 0)
128+        goto error;
129     am->state = to;
130
131     if (to == NULL)
132@@ -6040,6 +6048,10 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
133     if (min == 0)
134 	xmlFAGenerateEpsilonTransition(am, from, to);
135     return(to);
136+
137+error:
138+    xmlRegFreeAtom(atom);
139+    return(NULL);
140 }
141
142 /**
143@@ -6076,6 +6088,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
144     if (atom == NULL)
145 	return(NULL);
146     atom->valuep = xmlStrdup(token);
147+    if (atom->valuep == NULL)
148+        goto error;
149     atom->data = data;
150     if (min == 0)
151 	atom->min = 1;
152@@ -6094,10 +6108,11 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
153     if (to == NULL) {
154 	to = xmlRegStatePush(am);
155         if (to == NULL)
156-            return(NULL);
157+            goto error;
158     }
159     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
160-    xmlRegAtomPush(am, atom);
161+    if (xmlRegAtomPush(am, atom) < 0)
162+        goto error;
163     am->state = to;
164
165     if (to == NULL)
166@@ -6107,6 +6122,10 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
167     if (min == 0)
168 	xmlFAGenerateEpsilonTransition(am, from, to);
169     return(to);
170+
171+error:
172+    xmlRegFreeAtom(atom);
173+    return(NULL);
174 }
175
176 /**
177@@ -6147,6 +6166,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
178 	return(NULL);
179     if ((token2 == NULL) || (*token2 == 0)) {
180 	atom->valuep = xmlStrdup(token);
181+        if (atom->valuep == NULL)
182+            goto error;
183     } else {
184 	int lenn, lenp;
185 	xmlChar *str;
186@@ -6155,10 +6176,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
187 	lenp = strlen((char *) token);
188
189 	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
190-	if (str == NULL) {
191-	    xmlRegFreeAtom(atom);
192-	    return(NULL);
193-	}
194+	if (str == NULL)
195+	    goto error;
196 	memcpy(&str[0], token, lenp);
197 	str[lenp] = '|';
198 	memcpy(&str[lenp + 1], token2, lenn);
199@@ -6181,12 +6200,17 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
200     if (to == NULL) {
201 	to = xmlRegStatePush(am);
202         if (to == NULL)
203-            return(NULL);
204+            goto error;
205     }
206     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
207-    xmlRegAtomPush(am, atom);
208+    if (xmlRegAtomPush(am, atom) < 0)
209+        goto error;
210     am->state = to;
211     return(to);
212+
213+error:
214+    xmlRegFreeAtom(atom);
215+    return(NULL);
216 }
217
218
219@@ -6241,12 +6265,17 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
220     if (to == NULL) {
221 	to = xmlRegStatePush(am);
222         if (to == NULL)
223-            return(NULL);
224+            goto error;
225     }
226     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
227-    xmlRegAtomPush(am, atom);
228+    if (xmlRegAtomPush(am, atom) < 0)
229+        goto error;
230     am->state = to;
231     return(to);
232+
233+error:
234+    xmlRegFreeAtom(atom);
235+    return(NULL);
236 }
237
238 /**
239--
2402.27.0
241
242