Blame SOURCES/libxml2-2.9.13-CVE-2022-40304.patch

92a3a1
From 1b41ec4e9433b05bb0376be4725804c54ef1d80b Mon Sep 17 00:00:00 2001
92a3a1
From: Nick Wellnhofer <wellnhofer@aevum.de>
92a3a1
Date: Wed, 31 Aug 2022 22:11:25 +0200
92a3a1
Subject: [PATCH] [CVE-2022-40304] Fix dict corruption caused by entity
92a3a1
 reference cycles
92a3a1
92a3a1
When an entity reference cycle is detected, the entity content is
92a3a1
cleared by setting its first byte to zero. But the entity content might
92a3a1
be allocated from a dict. In this case, the dict entry becomes corrupted
92a3a1
leading to all kinds of logic errors, including memory errors like
92a3a1
double-frees.
92a3a1
92a3a1
Stop storing entity content, orig, ExternalID and SystemID in a dict.
92a3a1
These values are unlikely to occur multiple times in a document, so they
92a3a1
shouldn't have been stored in a dict in the first place.
92a3a1
92a3a1
Thanks to Ned Williamson and Nathan Wachholz working with Google Project
92a3a1
Zero for the report!
92a3a1
---
92a3a1
 entities.c | 55 ++++++++++++++++--------------------------------------
92a3a1
 1 file changed, 16 insertions(+), 39 deletions(-)
92a3a1
92a3a1
diff --git a/entities.c b/entities.c
92a3a1
index 84435515..d4e5412e 100644
92a3a1
--- a/entities.c
92a3a1
+++ b/entities.c
92a3a1
@@ -128,36 +128,19 @@ xmlFreeEntity(xmlEntityPtr entity)
92a3a1
     if ((entity->children) && (entity->owner == 1) &&
92a3a1
         (entity == (xmlEntityPtr) entity->children->parent))
92a3a1
         xmlFreeNodeList(entity->children);
92a3a1
-    if (dict != NULL) {
92a3a1
-        if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name)))
92a3a1
-            xmlFree((char *) entity->name);
92a3a1
-        if ((entity->ExternalID != NULL) &&
92a3a1
-	    (!xmlDictOwns(dict, entity->ExternalID)))
92a3a1
-            xmlFree((char *) entity->ExternalID);
92a3a1
-        if ((entity->SystemID != NULL) &&
92a3a1
-	    (!xmlDictOwns(dict, entity->SystemID)))
92a3a1
-            xmlFree((char *) entity->SystemID);
92a3a1
-        if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI)))
92a3a1
-            xmlFree((char *) entity->URI);
92a3a1
-        if ((entity->content != NULL)
92a3a1
-            && (!xmlDictOwns(dict, entity->content)))
92a3a1
-            xmlFree((char *) entity->content);
92a3a1
-        if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig)))
92a3a1
-            xmlFree((char *) entity->orig);
92a3a1
-    } else {
92a3a1
-        if (entity->name != NULL)
92a3a1
-            xmlFree((char *) entity->name);
92a3a1
-        if (entity->ExternalID != NULL)
92a3a1
-            xmlFree((char *) entity->ExternalID);
92a3a1
-        if (entity->SystemID != NULL)
92a3a1
-            xmlFree((char *) entity->SystemID);
92a3a1
-        if (entity->URI != NULL)
92a3a1
-            xmlFree((char *) entity->URI);
92a3a1
-        if (entity->content != NULL)
92a3a1
-            xmlFree((char *) entity->content);
92a3a1
-        if (entity->orig != NULL)
92a3a1
-            xmlFree((char *) entity->orig);
92a3a1
-    }
92a3a1
+    if ((entity->name != NULL) &&
92a3a1
+        ((dict == NULL) || (!xmlDictOwns(dict, entity->name))))
92a3a1
+        xmlFree((char *) entity->name);
92a3a1
+    if (entity->ExternalID != NULL)
92a3a1
+        xmlFree((char *) entity->ExternalID);
92a3a1
+    if (entity->SystemID != NULL)
92a3a1
+        xmlFree((char *) entity->SystemID);
92a3a1
+    if (entity->URI != NULL)
92a3a1
+        xmlFree((char *) entity->URI);
92a3a1
+    if (entity->content != NULL)
92a3a1
+        xmlFree((char *) entity->content);
92a3a1
+    if (entity->orig != NULL)
92a3a1
+        xmlFree((char *) entity->orig);
92a3a1
     xmlFree(entity);
92a3a1
 }
92a3a1
 
92a3a1
@@ -193,18 +176,12 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
92a3a1
 	    ret->SystemID = xmlStrdup(SystemID);
92a3a1
     } else {
92a3a1
         ret->name = xmlDictLookup(dict, name, -1);
92a3a1
-	if (ExternalID != NULL)
92a3a1
-	    ret->ExternalID = xmlDictLookup(dict, ExternalID, -1);
92a3a1
-	if (SystemID != NULL)
92a3a1
-	    ret->SystemID = xmlDictLookup(dict, SystemID, -1);
92a3a1
+	ret->ExternalID = xmlStrdup(ExternalID);
92a3a1
+	ret->SystemID = xmlStrdup(SystemID);
92a3a1
     }
92a3a1
     if (content != NULL) {
92a3a1
         ret->length = xmlStrlen(content);
92a3a1
-	if ((dict != NULL) && (ret->length < 5))
92a3a1
-	    ret->content = (xmlChar *)
92a3a1
-	                   xmlDictLookup(dict, content, ret->length);
92a3a1
-	else
92a3a1
-	    ret->content = xmlStrndup(content, ret->length);
92a3a1
+	ret->content = xmlStrndup(content, ret->length);
92a3a1
      } else {
92a3a1
         ret->length = 0;
92a3a1
         ret->content = NULL;
92a3a1
-- 
92a3a1
GitLab
92a3a1