153aa9179Sopenharmony_ciFrom e64653c0e7975594e27d7de2ed4be062c1e4ad03 Mon Sep 17 00:00:00 2001 253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de> 353aa9179Sopenharmony_ciDate: Fri, 17 Feb 2023 15:20:33 +0100 453aa9179Sopenharmony_ciSubject: [PATCH] malloc-fail: Fix leak of xmlRegAtom 553aa9179Sopenharmony_ci 653aa9179Sopenharmony_ciFound with libFuzzer, see #344. 753aa9179Sopenharmony_ci 853aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/e64653c0e7975594e27d7de2ed4be062c1e4ad03 953aa9179Sopenharmony_ciConflict:NA 1053aa9179Sopenharmony_ci--- 1153aa9179Sopenharmony_ci xmlregexp.c | 81 ++++++++++++++++++++++++++++++++++++----------------- 1253aa9179Sopenharmony_ci 1 file changed, 55 insertions(+), 26 deletions(-) 1353aa9179Sopenharmony_ci 1453aa9179Sopenharmony_cidiff --git a/xmlregexp.c b/xmlregexp.c 1553aa9179Sopenharmony_ciindex 8c2ea81..11c684a 100644 1653aa9179Sopenharmony_ci--- a/xmlregexp.c 1753aa9179Sopenharmony_ci+++ b/xmlregexp.c 1853aa9179Sopenharmony_ci@@ -1594,9 +1594,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 1953aa9179Sopenharmony_ci * this is a subexpression handling one should not need to 2053aa9179Sopenharmony_ci * create a new node except for XML_REGEXP_QUANT_RANGE. 2153aa9179Sopenharmony_ci */ 2253aa9179Sopenharmony_ci- if (xmlRegAtomPush(ctxt, atom) < 0) { 2353aa9179Sopenharmony_ci- return(-1); 2453aa9179Sopenharmony_ci- } 2553aa9179Sopenharmony_ci if ((to != NULL) && (atom->stop != to) && 2653aa9179Sopenharmony_ci (atom->quant != XML_REGEXP_QUANT_RANGE)) { 2753aa9179Sopenharmony_ci /* 2853aa9179Sopenharmony_ci@@ -1678,8 +1675,10 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 2953aa9179Sopenharmony_ci copy->max = 0; 3053aa9179Sopenharmony_ci 3153aa9179Sopenharmony_ci if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy) 3253aa9179Sopenharmony_ci- < 0) 3353aa9179Sopenharmony_ci+ < 0) { 3453aa9179Sopenharmony_ci+ xmlRegFreeAtom(copy); 3553aa9179Sopenharmony_ci return(-1); 3653aa9179Sopenharmony_ci+ } 3753aa9179Sopenharmony_ci inter = ctxt->state; 3853aa9179Sopenharmony_ci counter = xmlRegGetCounter(ctxt); 3953aa9179Sopenharmony_ci ctxt->counters[counter].min = atom->min - 1; 4053aa9179Sopenharmony_ci@@ -1722,6 +1721,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 4153aa9179Sopenharmony_ci default: 4253aa9179Sopenharmony_ci break; 4353aa9179Sopenharmony_ci } 4453aa9179Sopenharmony_ci+ if (xmlRegAtomPush(ctxt, atom) < 0) 4553aa9179Sopenharmony_ci+ return(-1); 4653aa9179Sopenharmony_ci return(0); 4753aa9179Sopenharmony_ci } 4853aa9179Sopenharmony_ci if ((atom->min == 0) && (atom->max == 0) && 4953aa9179Sopenharmony_ci@@ -1760,9 +1761,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 5053aa9179Sopenharmony_ci xmlFAGenerateEpsilonTransition(ctxt, tmp, to); 5153aa9179Sopenharmony_ci to = tmp; 5253aa9179Sopenharmony_ci } 5353aa9179Sopenharmony_ci- if (xmlRegAtomPush(ctxt, atom) < 0) { 5453aa9179Sopenharmony_ci- return(-1); 5553aa9179Sopenharmony_ci- } 5653aa9179Sopenharmony_ci if ((atom->quant == XML_REGEXP_QUANT_RANGE) && 5753aa9179Sopenharmony_ci (atom->min == 0) && (atom->max > 0)) { 5853aa9179Sopenharmony_ci nullable = 1; 5953aa9179Sopenharmony_ci@@ -1793,6 +1791,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 6053aa9179Sopenharmony_ci default: 6153aa9179Sopenharmony_ci break; 6253aa9179Sopenharmony_ci } 6353aa9179Sopenharmony_ci+ if (xmlRegAtomPush(ctxt, atom) < 0) 6453aa9179Sopenharmony_ci+ return(-1); 6553aa9179Sopenharmony_ci return(0); 6653aa9179Sopenharmony_ci } 6753aa9179Sopenharmony_ci 6853aa9179Sopenharmony_ci@@ -5447,8 +5447,12 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { 6953aa9179Sopenharmony_ci xmlFAGenerateEpsilonTransition(ctxt, previous, to); 7053aa9179Sopenharmony_ci } else { 7153aa9179Sopenharmony_ci if (xmlFAGenerateTransitions(ctxt, previous, 7253aa9179Sopenharmony_ci- (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, ctxt->atom) < 0) 7353aa9179Sopenharmony_ci+ (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, 7453aa9179Sopenharmony_ci+ ctxt->atom) < 0) { 7553aa9179Sopenharmony_ci+ xmlRegFreeAtom(ctxt->atom); 7653aa9179Sopenharmony_ci+ ctxt->atom = NULL; 7753aa9179Sopenharmony_ci return(-1); 7853aa9179Sopenharmony_ci+ } 7953aa9179Sopenharmony_ci previous = ctxt->state; 8053aa9179Sopenharmony_ci ctxt->atom = NULL; 8153aa9179Sopenharmony_ci } 8253aa9179Sopenharmony_ci@@ -5457,8 +5461,11 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { 8353aa9179Sopenharmony_ci if (ret != 0) { 8453aa9179Sopenharmony_ci if (xmlFAGenerateTransitions(ctxt, previous, 8553aa9179Sopenharmony_ci (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, 8653aa9179Sopenharmony_ci- ctxt->atom) < 0) 8753aa9179Sopenharmony_ci- return(-1); 8853aa9179Sopenharmony_ci+ ctxt->atom) < 0) { 8953aa9179Sopenharmony_ci+ xmlRegFreeAtom(ctxt->atom); 9053aa9179Sopenharmony_ci+ ctxt->atom = NULL; 9153aa9179Sopenharmony_ci+ return(-1); 9253aa9179Sopenharmony_ci+ } 9353aa9179Sopenharmony_ci previous = ctxt->state; 9453aa9179Sopenharmony_ci ctxt->atom = NULL; 9553aa9179Sopenharmony_ci } 9653aa9179Sopenharmony_ci@@ -5990,6 +5997,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 9753aa9179Sopenharmony_ci return(NULL); 9853aa9179Sopenharmony_ci if ((token2 == NULL) || (*token2 == 0)) { 9953aa9179Sopenharmony_ci atom->valuep = xmlStrdup(token); 10053aa9179Sopenharmony_ci+ if (atom->valuep == NULL) 10153aa9179Sopenharmony_ci+ goto error; 10253aa9179Sopenharmony_ci } else { 10353aa9179Sopenharmony_ci int lenn, lenp; 10453aa9179Sopenharmony_ci xmlChar *str; 10553aa9179Sopenharmony_ci@@ -5998,10 +6007,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 10653aa9179Sopenharmony_ci lenp = strlen((char *) token); 10753aa9179Sopenharmony_ci 10853aa9179Sopenharmony_ci str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 10953aa9179Sopenharmony_ci- if (str == NULL) { 11053aa9179Sopenharmony_ci- xmlRegFreeAtom(atom); 11153aa9179Sopenharmony_ci- return(NULL); 11253aa9179Sopenharmony_ci- } 11353aa9179Sopenharmony_ci+ if (str == NULL) 11453aa9179Sopenharmony_ci+ goto error; 11553aa9179Sopenharmony_ci memcpy(&str[0], token, lenp); 11653aa9179Sopenharmony_ci str[lenp] = '|'; 11753aa9179Sopenharmony_ci memcpy(&str[lenp + 1], token2, lenn); 11853aa9179Sopenharmony_ci@@ -6027,10 +6034,11 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 11953aa9179Sopenharmony_ci if (to == NULL) { 12053aa9179Sopenharmony_ci to = xmlRegStatePush(am); 12153aa9179Sopenharmony_ci if (to == NULL) 12253aa9179Sopenharmony_ci- return(NULL); 12353aa9179Sopenharmony_ci+ goto error; 12453aa9179Sopenharmony_ci } 12553aa9179Sopenharmony_ci xmlRegStateAddTrans(am, from, atom, to, counter, -1); 12653aa9179Sopenharmony_ci- xmlRegAtomPush(am, atom); 12753aa9179Sopenharmony_ci+ if (xmlRegAtomPush(am, atom) < 0) 12853aa9179Sopenharmony_ci+ goto error; 12953aa9179Sopenharmony_ci am->state = to; 13053aa9179Sopenharmony_ci 13153aa9179Sopenharmony_ci if (to == NULL) 13253aa9179Sopenharmony_ci@@ -6040,6 +6048,10 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 13353aa9179Sopenharmony_ci if (min == 0) 13453aa9179Sopenharmony_ci xmlFAGenerateEpsilonTransition(am, from, to); 13553aa9179Sopenharmony_ci return(to); 13653aa9179Sopenharmony_ci+ 13753aa9179Sopenharmony_ci+error: 13853aa9179Sopenharmony_ci+ xmlRegFreeAtom(atom); 13953aa9179Sopenharmony_ci+ return(NULL); 14053aa9179Sopenharmony_ci } 14153aa9179Sopenharmony_ci 14253aa9179Sopenharmony_ci /** 14353aa9179Sopenharmony_ci@@ -6076,6 +6088,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 14453aa9179Sopenharmony_ci if (atom == NULL) 14553aa9179Sopenharmony_ci return(NULL); 14653aa9179Sopenharmony_ci atom->valuep = xmlStrdup(token); 14753aa9179Sopenharmony_ci+ if (atom->valuep == NULL) 14853aa9179Sopenharmony_ci+ goto error; 14953aa9179Sopenharmony_ci atom->data = data; 15053aa9179Sopenharmony_ci if (min == 0) 15153aa9179Sopenharmony_ci atom->min = 1; 15253aa9179Sopenharmony_ci@@ -6094,10 +6108,11 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 15353aa9179Sopenharmony_ci if (to == NULL) { 15453aa9179Sopenharmony_ci to = xmlRegStatePush(am); 15553aa9179Sopenharmony_ci if (to == NULL) 15653aa9179Sopenharmony_ci- return(NULL); 15753aa9179Sopenharmony_ci+ goto error; 15853aa9179Sopenharmony_ci } 15953aa9179Sopenharmony_ci xmlRegStateAddTrans(am, from, atom, to, counter, -1); 16053aa9179Sopenharmony_ci- xmlRegAtomPush(am, atom); 16153aa9179Sopenharmony_ci+ if (xmlRegAtomPush(am, atom) < 0) 16253aa9179Sopenharmony_ci+ goto error; 16353aa9179Sopenharmony_ci am->state = to; 16453aa9179Sopenharmony_ci 16553aa9179Sopenharmony_ci if (to == NULL) 16653aa9179Sopenharmony_ci@@ -6107,6 +6122,10 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 16753aa9179Sopenharmony_ci if (min == 0) 16853aa9179Sopenharmony_ci xmlFAGenerateEpsilonTransition(am, from, to); 16953aa9179Sopenharmony_ci return(to); 17053aa9179Sopenharmony_ci+ 17153aa9179Sopenharmony_ci+error: 17253aa9179Sopenharmony_ci+ xmlRegFreeAtom(atom); 17353aa9179Sopenharmony_ci+ return(NULL); 17453aa9179Sopenharmony_ci } 17553aa9179Sopenharmony_ci 17653aa9179Sopenharmony_ci /** 17753aa9179Sopenharmony_ci@@ -6147,6 +6166,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 17853aa9179Sopenharmony_ci return(NULL); 17953aa9179Sopenharmony_ci if ((token2 == NULL) || (*token2 == 0)) { 18053aa9179Sopenharmony_ci atom->valuep = xmlStrdup(token); 18153aa9179Sopenharmony_ci+ if (atom->valuep == NULL) 18253aa9179Sopenharmony_ci+ goto error; 18353aa9179Sopenharmony_ci } else { 18453aa9179Sopenharmony_ci int lenn, lenp; 18553aa9179Sopenharmony_ci xmlChar *str; 18653aa9179Sopenharmony_ci@@ -6155,10 +6176,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 18753aa9179Sopenharmony_ci lenp = strlen((char *) token); 18853aa9179Sopenharmony_ci 18953aa9179Sopenharmony_ci str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 19053aa9179Sopenharmony_ci- if (str == NULL) { 19153aa9179Sopenharmony_ci- xmlRegFreeAtom(atom); 19253aa9179Sopenharmony_ci- return(NULL); 19353aa9179Sopenharmony_ci- } 19453aa9179Sopenharmony_ci+ if (str == NULL) 19553aa9179Sopenharmony_ci+ goto error; 19653aa9179Sopenharmony_ci memcpy(&str[0], token, lenp); 19753aa9179Sopenharmony_ci str[lenp] = '|'; 19853aa9179Sopenharmony_ci memcpy(&str[lenp + 1], token2, lenn); 19953aa9179Sopenharmony_ci@@ -6181,12 +6200,17 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 20053aa9179Sopenharmony_ci if (to == NULL) { 20153aa9179Sopenharmony_ci to = xmlRegStatePush(am); 20253aa9179Sopenharmony_ci if (to == NULL) 20353aa9179Sopenharmony_ci- return(NULL); 20453aa9179Sopenharmony_ci+ goto error; 20553aa9179Sopenharmony_ci } 20653aa9179Sopenharmony_ci xmlRegStateAddTrans(am, from, atom, to, counter, -1); 20753aa9179Sopenharmony_ci- xmlRegAtomPush(am, atom); 20853aa9179Sopenharmony_ci+ if (xmlRegAtomPush(am, atom) < 0) 20953aa9179Sopenharmony_ci+ goto error; 21053aa9179Sopenharmony_ci am->state = to; 21153aa9179Sopenharmony_ci return(to); 21253aa9179Sopenharmony_ci+ 21353aa9179Sopenharmony_ci+error: 21453aa9179Sopenharmony_ci+ xmlRegFreeAtom(atom); 21553aa9179Sopenharmony_ci+ return(NULL); 21653aa9179Sopenharmony_ci } 21753aa9179Sopenharmony_ci 21853aa9179Sopenharmony_ci 21953aa9179Sopenharmony_ci@@ -6241,12 +6265,17 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 22053aa9179Sopenharmony_ci if (to == NULL) { 22153aa9179Sopenharmony_ci to = xmlRegStatePush(am); 22253aa9179Sopenharmony_ci if (to == NULL) 22353aa9179Sopenharmony_ci- return(NULL); 22453aa9179Sopenharmony_ci+ goto error; 22553aa9179Sopenharmony_ci } 22653aa9179Sopenharmony_ci xmlRegStateAddTrans(am, from, atom, to, counter, -1); 22753aa9179Sopenharmony_ci- xmlRegAtomPush(am, atom); 22853aa9179Sopenharmony_ci+ if (xmlRegAtomPush(am, atom) < 0) 22953aa9179Sopenharmony_ci+ goto error; 23053aa9179Sopenharmony_ci am->state = to; 23153aa9179Sopenharmony_ci return(to); 23253aa9179Sopenharmony_ci+ 23353aa9179Sopenharmony_ci+error: 23453aa9179Sopenharmony_ci+ xmlRegFreeAtom(atom); 23553aa9179Sopenharmony_ci+ return(NULL); 23653aa9179Sopenharmony_ci } 23753aa9179Sopenharmony_ci 23853aa9179Sopenharmony_ci /** 23953aa9179Sopenharmony_ci-- 24053aa9179Sopenharmony_ci2.27.0 24153aa9179Sopenharmony_ci 242