1From ec05f04d8b5a0a60515235f65ed1256644a77741 Mon Sep 17 00:00:00 2001 2From: Nick Wellnhofer <wellnhofer@aevum.de> 3Date: Thu, 16 Feb 2023 12:40:02 +0100 4Subject: [PATCH] malloc-fail: Fix memory leak in xmlXIncludeLoadTxt 5 6Found with libFuzzer, see #344. 7 8Reference:https://github.com/GNOME/libxml2/commit/ec05f04d8b5a0a60515235f65ed1256644a77741 9Conflict:xinclude.c 10 11--- 12 xinclude.c | 67 +++++++++++++++++++++++------------------------------- 13 1 file changed, 28 insertions(+), 39 deletions(-) 14 15diff --git a/xinclude.c b/xinclude.c 16index cc22848..c0b4439 100644 17--- a/xinclude.c 18+++ b/xinclude.c 19@@ -1791,14 +1791,15 @@ error: 20 static int 21 xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 22 xmlParserInputBufferPtr buf; 23- xmlNodePtr node; 24- xmlURIPtr uri; 25- xmlChar *URL; 26+ xmlNodePtr node = NULL; 27+ xmlURIPtr uri = NULL; 28+ xmlChar *URL = NULL; 29 int i; 30+ int ret = -1; 31 xmlChar *encoding = NULL; 32 xmlCharEncoding enc = (xmlCharEncoding) 0; 33- xmlParserCtxtPtr pctxt; 34- xmlParserInputPtr inputStream; 35+ xmlParserCtxtPtr pctxt = NULL; 36+ xmlParserInputPtr inputStream = NULL; 37 int len; 38 const xmlChar *content; 39 40@@ -1814,21 +1815,19 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 41 if (uri == NULL) { 42 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, 43 "invalid value URI %s\n", url); 44- return(-1); 45+ goto error; 46 } 47 if (uri->fragment != NULL) { 48 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT, 49 "fragment identifier forbidden for text: %s\n", 50 (const xmlChar *) uri->fragment); 51- xmlFreeURI(uri); 52- return(-1); 53+ goto error; 54 } 55 URL = xmlSaveUri(uri); 56- xmlFreeURI(uri); 57 if (URL == NULL) { 58 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, 59 "invalid value URI %s\n", url); 60- return(-1); 61+ goto error; 62 } 63 64 /* 65@@ -1839,8 +1838,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 66 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 67 XML_XINCLUDE_TEXT_DOCUMENT, 68 "text serialization of document not available\n", NULL); 69- xmlFree(URL); 70- return(-1); 71+ goto error; 72 } 73 74 /* 75@@ -1870,11 +1868,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 76 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 77 XML_XINCLUDE_UNKNOWN_ENCODING, 78 "encoding %s not supported\n", encoding); 79- xmlFree(encoding); 80- xmlFree(URL); 81- return(-1); 82+ goto error; 83 } 84- xmlFree(encoding); 85 } 86 87 /* 88@@ -1882,27 +1877,18 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 89 */ 90 pctxt = xmlNewParserCtxt(); 91 inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt); 92- if(inputStream == NULL) { 93- xmlFreeParserCtxt(pctxt); 94- xmlFree(URL); 95- return(-1); 96- } 97+ if(inputStream == NULL) 98+ goto error; 99 buf = inputStream->buf; 100- if (buf == NULL) { 101- xmlFreeInputStream (inputStream); 102- xmlFreeParserCtxt(pctxt); 103- xmlFree(URL); 104- return(-1); 105- } 106+ if (buf == NULL) 107+ goto error; 108 if (buf->encoder) 109 xmlCharEncCloseFunc(buf->encoder); 110 buf->encoder = xmlGetCharEncodingHandler(enc); 111 node = xmlNewText(NULL); 112 if (node == NULL) { 113- xmlFreeInputStream(inputStream); 114- xmlFreeParserCtxt(pctxt); 115- xmlFree(URL); 116- return(-1); 117+ xmlXIncludeErrMemory(ctxt, ctxt->incTab[nr]->ref, NULL); 118+ goto error; 119 } 120 121 /* 122@@ -1921,28 +1907,31 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { 123 if (!IS_CHAR(cur)) { 124 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR, 125 "%s contains invalid char\n", URL); 126- xmlFreeNode(node); 127- xmlFreeInputStream(inputStream); 128- xmlFreeParserCtxt(pctxt); 129- xmlFree(URL); 130- return(-1); 131+ goto error; 132 } 133 134 i += l; 135 } 136 137 xmlNodeAddContentLen(node, content, len); 138- xmlFreeParserCtxt(pctxt); 139 xmlXIncludeAddTxt(ctxt, node->content, URL); 140- xmlFreeInputStream(inputStream); 141 142 loaded: 143 /* 144 * Add the element as the replacement copy. 145 */ 146 ctxt->incTab[nr]->inc = node; 147+ node = NULL; 148+ ret = 0; 149+ 150+error: 151+ xmlFreeNode(node); 152+ xmlFreeInputStream(inputStream); 153+ xmlFreeParserCtxt(pctxt); 154+ xmlFree(encoding); 155+ xmlFreeURI(uri); 156 xmlFree(URL); 157- return(0); 158+ return(ret); 159 } 160 161 /** 162-- 1632.27.0 164 165