|
|
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 |
|