xzyang / rpms / libxml2

Forked from rpms/libxml2 3 years ago
Clone

Blame SOURCES/libxml2-2.9.7-CVE-2021-3541.patch

bc5a00
From 8598060bacada41a0eb09d95c97744ff4e428f8e Mon Sep 17 00:00:00 2001
bc5a00
From: Daniel Veillard <veillard@redhat.com>
bc5a00
Date: Thu, 13 May 2021 14:55:12 +0200
bc5a00
Subject: [PATCH] Patch for security issue CVE-2021-3541
bc5a00
bc5a00
This is relapted to parameter entities expansion and following
bc5a00
the line of the billion laugh attack. Somehow in that path the
bc5a00
counting of parameters was missed and the normal algorithm based
bc5a00
on entities "density" was useless.
bc5a00
---
bc5a00
 parser.c | 26 ++++++++++++++++++++++++++
bc5a00
 1 file changed, 26 insertions(+)
bc5a00
bc5a00
diff --git a/parser.c b/parser.c
bc5a00
index f5e5e169..c9312fa4 100644
bc5a00
--- a/parser.c
bc5a00
+++ b/parser.c
bc5a00
@@ -140,6 +140,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
bc5a00
                      xmlEntityPtr ent, size_t replacement)
bc5a00
 {
bc5a00
     size_t consumed = 0;
bc5a00
+    int i;
bc5a00
 
bc5a00
     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
bc5a00
         return (0);
bc5a00
@@ -177,6 +178,28 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
bc5a00
 	    rep = NULL;
bc5a00
 	}
bc5a00
     }
bc5a00
+
bc5a00
+    /*
bc5a00
+     * Prevent entity exponential check, not just replacement while
bc5a00
+     * parsing the DTD
bc5a00
+     * The check is potentially costly so do that only once in a thousand
bc5a00
+     */
bc5a00
+    if ((ctxt->instate == XML_PARSER_DTD) && (ctxt->nbentities > 10000) &&
bc5a00
+        (ctxt->nbentities % 1024 == 0)) {
bc5a00
+	for (i = 0;i < ctxt->inputNr;i++) {
bc5a00
+	    consumed += ctxt->inputTab[i]->consumed +
bc5a00
+	               (ctxt->inputTab[i]->cur - ctxt->inputTab[i]->base);
bc5a00
+	}
bc5a00
+	if (ctxt->nbentities > consumed * XML_PARSER_NON_LINEAR) {
bc5a00
+	    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
bc5a00
+	    ctxt->instate = XML_PARSER_EOF;
bc5a00
+	    return (1);
bc5a00
+	}
bc5a00
+	consumed = 0;
bc5a00
+    }
bc5a00
+
bc5a00
+
bc5a00
+
bc5a00
     if (replacement != 0) {
bc5a00
 	if (replacement < XML_MAX_TEXT_LENGTH)
bc5a00
 	    return(0);
bc5a00
@@ -7963,6 +7986,9 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
bc5a00
             xmlChar start[4];
bc5a00
             xmlCharEncoding enc;
bc5a00
 
bc5a00
+	    if (xmlParserEntityCheck(ctxt, 0, entity, 0))
bc5a00
+	        return;
bc5a00
+
bc5a00
 	    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
bc5a00
 	        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
bc5a00
 		((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
bc5a00
-- 
bc5a00
GitLab
bc5a00