From cd31becb839ee91732a2639e0300638c026ccf12 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 1 Nov 2022 23:46:13 +0000 Subject: [PATCH] Fix CVE-2022-40304 (#2136569) Resolves: #2136569 --- libxml2-2.9.13-CVE-2022-40304.patch | 101 ++++++++++++++++++++++++++++ libxml2.spec | 3 + 2 files changed, 104 insertions(+) create mode 100644 libxml2-2.9.13-CVE-2022-40304.patch diff --git a/libxml2-2.9.13-CVE-2022-40304.patch b/libxml2-2.9.13-CVE-2022-40304.patch new file mode 100644 index 0000000..b6a4858 --- /dev/null +++ b/libxml2-2.9.13-CVE-2022-40304.patch @@ -0,0 +1,101 @@ +From 1b41ec4e9433b05bb0376be4725804c54ef1d80b Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Wed, 31 Aug 2022 22:11:25 +0200 +Subject: [PATCH] [CVE-2022-40304] Fix dict corruption caused by entity + reference cycles + +When an entity reference cycle is detected, the entity content is +cleared by setting its first byte to zero. But the entity content might +be allocated from a dict. In this case, the dict entry becomes corrupted +leading to all kinds of logic errors, including memory errors like +double-frees. + +Stop storing entity content, orig, ExternalID and SystemID in a dict. +These values are unlikely to occur multiple times in a document, so they +shouldn't have been stored in a dict in the first place. + +Thanks to Ned Williamson and Nathan Wachholz working with Google Project +Zero for the report! +--- + entities.c | 55 ++++++++++++++++-------------------------------------- + 1 file changed, 16 insertions(+), 39 deletions(-) + +diff --git a/entities.c b/entities.c +index 84435515..d4e5412e 100644 +--- a/entities.c ++++ b/entities.c +@@ -128,36 +128,19 @@ xmlFreeEntity(xmlEntityPtr entity) + if ((entity->children) && (entity->owner == 1) && + (entity == (xmlEntityPtr) entity->children->parent)) + xmlFreeNodeList(entity->children); +- if (dict != NULL) { +- if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name))) +- xmlFree((char *) entity->name); +- if ((entity->ExternalID != NULL) && +- (!xmlDictOwns(dict, entity->ExternalID))) +- xmlFree((char *) entity->ExternalID); +- if ((entity->SystemID != NULL) && +- (!xmlDictOwns(dict, entity->SystemID))) +- xmlFree((char *) entity->SystemID); +- if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI))) +- xmlFree((char *) entity->URI); +- if ((entity->content != NULL) +- && (!xmlDictOwns(dict, entity->content))) +- xmlFree((char *) entity->content); +- if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig))) +- xmlFree((char *) entity->orig); +- } else { +- if (entity->name != NULL) +- xmlFree((char *) entity->name); +- if (entity->ExternalID != NULL) +- xmlFree((char *) entity->ExternalID); +- if (entity->SystemID != NULL) +- xmlFree((char *) entity->SystemID); +- if (entity->URI != NULL) +- xmlFree((char *) entity->URI); +- if (entity->content != NULL) +- xmlFree((char *) entity->content); +- if (entity->orig != NULL) +- xmlFree((char *) entity->orig); +- } ++ if ((entity->name != NULL) && ++ ((dict == NULL) || (!xmlDictOwns(dict, entity->name)))) ++ xmlFree((char *) entity->name); ++ if (entity->ExternalID != NULL) ++ xmlFree((char *) entity->ExternalID); ++ if (entity->SystemID != NULL) ++ xmlFree((char *) entity->SystemID); ++ if (entity->URI != NULL) ++ xmlFree((char *) entity->URI); ++ if (entity->content != NULL) ++ xmlFree((char *) entity->content); ++ if (entity->orig != NULL) ++ xmlFree((char *) entity->orig); + xmlFree(entity); + } + +@@ -193,18 +176,12 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type, + ret->SystemID = xmlStrdup(SystemID); + } else { + ret->name = xmlDictLookup(dict, name, -1); +- if (ExternalID != NULL) +- ret->ExternalID = xmlDictLookup(dict, ExternalID, -1); +- if (SystemID != NULL) +- ret->SystemID = xmlDictLookup(dict, SystemID, -1); ++ ret->ExternalID = xmlStrdup(ExternalID); ++ ret->SystemID = xmlStrdup(SystemID); + } + if (content != NULL) { + ret->length = xmlStrlen(content); +- if ((dict != NULL) && (ret->length < 5)) +- ret->content = (xmlChar *) +- xmlDictLookup(dict, content, ret->length); +- else +- ret->content = xmlStrndup(content, ret->length); ++ ret->content = xmlStrndup(content, ret->length); + } else { + ret->length = 0; + ret->content = NULL; +-- +GitLab + diff --git a/libxml2.spec b/libxml2.spec index d9300dd..8a33c83 100644 --- a/libxml2.spec +++ b/libxml2.spec @@ -14,6 +14,8 @@ Patch1: libxml2-2.9.8-python3-unicode-errors.patch Patch2: libxml2-2.9.13-CVE-2022-29824.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2136564 Patch3: libxml2-2.9.13-CVE-2022-40303.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2136569 +Patch4: libxml2-2.9.13-CVE-2022-40304.patch BuildRequires: cmake-rpm-macros BuildRequires: gcc @@ -144,6 +146,7 @@ gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz %changelog * Tue Nov 01 2022 David King - 2.9.13-3 - Fix CVE-2022-40303 (#2136564) +- Fix CVE-2022-40304 (#2136569) * Tue May 10 2022 David King - 2.9.13-2 - Fix CVE-2022-29824 (#2082300)