xzyang / rpms / libxml2

Forked from rpms/libxml2 3 years ago
Clone

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

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