1From 9fa1b228a5d60fab92a79c6c01c39e37454da1b3 Mon Sep 17 00:00:00 2001 2From: Nick Wellnhofer <wellnhofer@aevum.de> 3Date: Tue, 14 Feb 2023 16:43:35 +0100 4Subject: [PATCH] malloc-fail: Fix memory leak in xmlGetDtdElementDesc2 5 6Found with libFuzzer, see #344. 7 8Reference:https://github.com/GNOME/libxml2/commit/9fa1b228a5d60fab92a79c6c01c39e37454da1b3 9Conflict:valid.c 10 11--- 12 valid.c | 23 +++++++++++++++-------- 13 1 file changed, 15 insertions(+), 8 deletions(-) 14 15diff --git a/valid.c b/valid.c 16index ed3c850..b7b92fe 100644 17--- a/valid.c 18+++ b/valid.c 19@@ -26,8 +26,9 @@ 20 #include <libxml/list.h> 21 #include <libxml/globals.h> 22 23-static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, 24- int create); 25+static xmlElementPtr 26+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name, 27+ int create); 28 /* #define DEBUG_VALID_ALGO */ 29 /* #define DEBUG_REGEXP_ALGO */ 30 31@@ -2135,7 +2136,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, 32 * Validity Check: 33 * Multiple ID per element 34 */ 35- elemDef = xmlGetDtdElementDesc2(dtd, elem, 1); 36+ elemDef = xmlGetDtdElementDesc2(ctxt, dtd, elem, 1); 37 if (elemDef != NULL) { 38 39 #ifdef LIBXML_VALID_ENABLED 40@@ -3295,7 +3296,8 @@ xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) { 41 */ 42 43 static xmlElementPtr 44-xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) { 45+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name, 46+ int create) { 47 xmlElementTablePtr table; 48 xmlElementPtr cur; 49 xmlChar *uqname = NULL, *prefix = NULL; 50@@ -3318,7 +3320,7 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) { 51 dtd->elements = (void *) table; 52 } 53 if (table == NULL) { 54- xmlVErrMemory(NULL, "element table allocation failed"); 55+ xmlVErrMemory(ctxt, "element table allocation failed"); 56 return(NULL); 57 } 58 } 59@@ -3331,8 +3333,8 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) { 60 if ((cur == NULL) && (create)) { 61 cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement)); 62 if (cur == NULL) { 63- xmlVErrMemory(NULL, "malloc failed"); 64- return(NULL); 65+ xmlVErrMemory(ctxt, "malloc failed"); 66+ goto error; 67 } 68 memset(cur, 0, sizeof(xmlElement)); 69 cur->type = XML_ELEMENT_DECL; 70@@ -3344,8 +3346,13 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) { 71 cur->prefix = xmlStrdup(prefix); 72 cur->etype = XML_ELEMENT_TYPE_UNDEFINED; 73 74- xmlHashAddEntry2(table, name, prefix, cur); 75+ if (xmlHashAddEntry2(table, name, prefix, cur) < 0) { 76+ xmlVErrMemory(ctxt, "adding entry failed"); 77+ xmlFreeElement(cur); 78+ cur = NULL; 79+ } 80 } 81+error: 82 if (prefix != NULL) xmlFree(prefix); 83 if (uqname != NULL) xmlFree(uqname); 84 return(cur); 85-- 862.27.0 87 88