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