From 5696c829fbbad704743c2b89069af200fc5f2ec2 Mon Sep 17 00:00:00 2001 From: Packit Date: Aug 25 2020 09:22:20 +0000 Subject: Apply patch libxml2-CVE-2016-9597.patch patch_name: libxml2-CVE-2016-9597.patch location_in_specfile: 4 present_in_specfile: true --- diff --git a/entities.c b/entities.c index c819337..59e72c7 100644 --- a/entities.c +++ b/entities.c @@ -164,6 +164,7 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type, memset(ret, 0, sizeof(xmlEntity)); ret->type = XML_ENTITY_DECL; ret->checked = 0; + ret->guard = XML_ENTITY_NOT_BEING_CHECKED; /* * fill the structure. @@ -936,6 +937,7 @@ xmlCopyEntity(xmlEntityPtr ent) { cur->orig = xmlStrdup(ent->orig); if (ent->URI != NULL) cur->URI = xmlStrdup(ent->URI); + cur->guard = 0; return(cur); } diff --git a/include/libxml/entities.h b/include/libxml/entities.h index 47b4573..52a6a97 100644 --- a/include/libxml/entities.h +++ b/include/libxml/entities.h @@ -30,6 +30,11 @@ typedef enum { XML_INTERNAL_PREDEFINED_ENTITY = 6 } xmlEntityType; +typedef enum { + XML_ENTITY_NOT_BEING_CHECKED, + XML_ENTITY_BEING_CHECKED /* entity check is in progress */ +} xmlEntityRecursionGuard; + /* * An unit of storage for an entity, contains the string, the value * and the linkind data needed for the linking in the hash table. @@ -60,6 +65,7 @@ struct _xmlEntity { /* this is also used to count entities * references done from that entity * and if it contains '<' */ + xmlEntityRecursionGuard guard; }; /* diff --git a/parser.c b/parser.c index 1c5e036..5bc9032 100644 --- a/parser.c +++ b/parser.c @@ -139,6 +139,10 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP) return (1); + if ((ent != NULL) && (ent->guard == XML_ENTITY_BEING_CHECKED)) { + xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); + return (1); + } /* * This may look absurd but is needed to detect * entities problems @@ -149,12 +153,14 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, unsigned long oldnbent = ctxt->nbentities; xmlChar *rep; + ent->guard = XML_ENTITY_BEING_CHECKED; ent->checked = 1; ++ctxt->depth; rep = xmlStringDecodeEntities(ctxt, ent->content, XML_SUBSTITUTE_REF, 0, 0, 0); --ctxt->depth; + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { ent->content[0] = 0; } @@ -7110,23 +7116,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { * if its replacement text matches the production labeled * content. */ - if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { - ctxt->depth++; - ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content, - user_data, &list); - ctxt->depth--; - - } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { - ctxt->depth++; - ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax, - user_data, ctxt->depth, ent->URI, - ent->ExternalID, &list); - ctxt->depth--; - } else { - ret = XML_ERR_ENTITY_PE_INTERNAL; - xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, - "invalid entity type found\n", NULL); - } + if (ent->guard == XML_ENTITY_BEING_CHECKED) { + ret = XML_ERR_ENTITY_LOOP; + } else { + ent->guard = XML_ENTITY_BEING_CHECKED; + if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { + ctxt->depth++; + ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content, + user_data, &list); + ctxt->depth--; + } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { + ctxt->depth++; + ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax, + user_data, ctxt->depth, ent->URI, + ent->ExternalID, &list); + ctxt->depth--; + } else { + ret = XML_ERR_ENTITY_PE_INTERNAL; + xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, + "invalid entity type found\n", NULL); + } + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; + } /* * Store the number of entities needing parsing for this entity @@ -7232,23 +7243,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { else user_data = ctxt->userData; - if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { - ctxt->depth++; - ret = xmlParseBalancedChunkMemoryInternal(ctxt, - ent->content, user_data, NULL); - ctxt->depth--; - } else if (ent->etype == - XML_EXTERNAL_GENERAL_PARSED_ENTITY) { - ctxt->depth++; - ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, - ctxt->sax, user_data, ctxt->depth, - ent->URI, ent->ExternalID, NULL); - ctxt->depth--; - } else { - ret = XML_ERR_ENTITY_PE_INTERNAL; - xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, - "invalid entity type found\n", NULL); - } + if (ent->guard == XML_ENTITY_BEING_CHECKED) { + ret = XML_ERR_ENTITY_LOOP; + } else { + ent->guard = XML_ENTITY_BEING_CHECKED; + if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { + ctxt->depth++; + ret = xmlParseBalancedChunkMemoryInternal(ctxt, + ent->content, user_data, NULL); + ctxt->depth--; + } else if (ent->etype == + XML_EXTERNAL_GENERAL_PARSED_ENTITY) { + ctxt->depth++; + ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, + ctxt->sax, user_data, ctxt->depth, + ent->URI, ent->ExternalID, NULL); + ctxt->depth--; + } else { + ret = XML_ERR_ENTITY_PE_INTERNAL; + xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, + "invalid entity type found\n", NULL); + } + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; + } if (ret == XML_ERR_ENTITY_LOOP) { xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); return;