From e64653c0e7975594e27d7de2ed4be062c1e4ad03 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Fri, 17 Feb 2023 15:20:33 +0100 Subject: [PATCH] malloc-fail: Fix leak of xmlRegAtom Found with libFuzzer, see #344. Reference:https://github.com/GNOME/libxml2/commit/e64653c0e7975594e27d7de2ed4be062c1e4ad03 Conflict:NA --- xmlregexp.c | 81 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/xmlregexp.c b/xmlregexp.c index 8c2ea81..11c684a 100644 --- a/xmlregexp.c +++ b/xmlregexp.c @@ -1594,9 +1594,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, * this is a subexpression handling one should not need to * create a new node except for XML_REGEXP_QUANT_RANGE. */ - if (xmlRegAtomPush(ctxt, atom) < 0) { - return(-1); - } if ((to != NULL) && (atom->stop != to) && (atom->quant != XML_REGEXP_QUANT_RANGE)) { /* @@ -1678,8 +1675,10 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, copy->max = 0; if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy) - < 0) + < 0) { + xmlRegFreeAtom(copy); return(-1); + } inter = ctxt->state; counter = xmlRegGetCounter(ctxt); ctxt->counters[counter].min = atom->min - 1; @@ -1722,6 +1721,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, default: break; } + if (xmlRegAtomPush(ctxt, atom) < 0) + return(-1); return(0); } if ((atom->min == 0) && (atom->max == 0) && @@ -1760,9 +1761,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, xmlFAGenerateEpsilonTransition(ctxt, tmp, to); to = tmp; } - if (xmlRegAtomPush(ctxt, atom) < 0) { - return(-1); - } if ((atom->quant == XML_REGEXP_QUANT_RANGE) && (atom->min == 0) && (atom->max > 0)) { nullable = 1; @@ -1793,6 +1791,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, default: break; } + if (xmlRegAtomPush(ctxt, atom) < 0) + return(-1); return(0); } @@ -5447,8 +5447,12 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { xmlFAGenerateEpsilonTransition(ctxt, previous, to); } else { if (xmlFAGenerateTransitions(ctxt, previous, - (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, ctxt->atom) < 0) + (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, + ctxt->atom) < 0) { + xmlRegFreeAtom(ctxt->atom); + ctxt->atom = NULL; return(-1); + } previous = ctxt->state; ctxt->atom = NULL; } @@ -5457,8 +5461,11 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { if (ret != 0) { if (xmlFAGenerateTransitions(ctxt, previous, (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, - ctxt->atom) < 0) - return(-1); + ctxt->atom) < 0) { + xmlRegFreeAtom(ctxt->atom); + ctxt->atom = NULL; + return(-1); + } previous = ctxt->state; ctxt->atom = NULL; } @@ -5990,6 +5997,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, return(NULL); if ((token2 == NULL) || (*token2 == 0)) { atom->valuep = xmlStrdup(token); + if (atom->valuep == NULL) + goto error; } else { int lenn, lenp; xmlChar *str; @@ -5998,10 +6007,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, lenp = strlen((char *) token); str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); - if (str == NULL) { - xmlRegFreeAtom(atom); - return(NULL); - } + if (str == NULL) + goto error; memcpy(&str[0], token, lenp); str[lenp] = '|'; memcpy(&str[lenp + 1], token2, lenn); @@ -6027,10 +6034,11 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, if (to == NULL) { to = xmlRegStatePush(am); if (to == NULL) - return(NULL); + goto error; } xmlRegStateAddTrans(am, from, atom, to, counter, -1); - xmlRegAtomPush(am, atom); + if (xmlRegAtomPush(am, atom) < 0) + goto error; am->state = to; if (to == NULL) @@ -6040,6 +6048,10 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, if (min == 0) xmlFAGenerateEpsilonTransition(am, from, to); return(to); + +error: + xmlRegFreeAtom(atom); + return(NULL); } /** @@ -6076,6 +6088,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, if (atom == NULL) return(NULL); atom->valuep = xmlStrdup(token); + if (atom->valuep == NULL) + goto error; atom->data = data; if (min == 0) atom->min = 1; @@ -6094,10 +6108,11 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, if (to == NULL) { to = xmlRegStatePush(am); if (to == NULL) - return(NULL); + goto error; } xmlRegStateAddTrans(am, from, atom, to, counter, -1); - xmlRegAtomPush(am, atom); + if (xmlRegAtomPush(am, atom) < 0) + goto error; am->state = to; if (to == NULL) @@ -6107,6 +6122,10 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, if (min == 0) xmlFAGenerateEpsilonTransition(am, from, to); return(to); + +error: + xmlRegFreeAtom(atom); + return(NULL); } /** @@ -6147,6 +6166,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, return(NULL); if ((token2 == NULL) || (*token2 == 0)) { atom->valuep = xmlStrdup(token); + if (atom->valuep == NULL) + goto error; } else { int lenn, lenp; xmlChar *str; @@ -6155,10 +6176,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, lenp = strlen((char *) token); str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); - if (str == NULL) { - xmlRegFreeAtom(atom); - return(NULL); - } + if (str == NULL) + goto error; memcpy(&str[0], token, lenp); str[lenp] = '|'; memcpy(&str[lenp + 1], token2, lenn); @@ -6181,12 +6200,17 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, if (to == NULL) { to = xmlRegStatePush(am); if (to == NULL) - return(NULL); + goto error; } xmlRegStateAddTrans(am, from, atom, to, counter, -1); - xmlRegAtomPush(am, atom); + if (xmlRegAtomPush(am, atom) < 0) + goto error; am->state = to; return(to); + +error: + xmlRegFreeAtom(atom); + return(NULL); } @@ -6241,12 +6265,17 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, if (to == NULL) { to = xmlRegStatePush(am); if (to == NULL) - return(NULL); + goto error; } xmlRegStateAddTrans(am, from, atom, to, counter, -1); - xmlRegAtomPush(am, atom); + if (xmlRegAtomPush(am, atom) < 0) + goto error; am->state = to; return(to); + +error: + xmlRegFreeAtom(atom); + return(NULL); } /** -- 2.27.0