summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@redhat.com>2021-05-13 14:55:12 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-11-18 11:26:59 +0000
commit78831e7aca3f82a0c64499706c8017c13389efa3 (patch)
tree02b91ba36e02450d1f882b79b2bbd0e5e274af61
parent655e5c958458cc792e8cc399b8b74139c50fa054 (diff)
downloadqtwebengine-chromium-78831e7aca3f82a0c64499706c8017c13389efa3.tar.gz
[Backport] CVE-2021-3541 libxml2: Exponential entity expansion attack bypasses all existing protection mechanisms
Manual backport of patch originally committed at https://gitlab.gnome.org/GNOME/libxml2/-/commit/8598060bacada41a0eb09d95c97744ff4e428f8e: Patch for security issue CVE-2021-3541 This is relapted to parameter entities expansion and following the line of the billion laugh attack. Somehow in that path the counting of parameters was missed and the normal algorithm based on entities "density" was useless. Change-Id: I81d1ab274ae80a9e0e0890dada92d3f09584e4e7 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/third_party/libxml/src/parser.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/chromium/third_party/libxml/src/parser.c b/chromium/third_party/libxml/src/parser.c
index 3a8a0d79e96..b1820be7163 100644
--- a/chromium/third_party/libxml/src/parser.c
+++ b/chromium/third_party/libxml/src/parser.c
@@ -127,6 +127,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
xmlEntityPtr ent, size_t replacement)
{
size_t consumed = 0;
+ int i;
if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
return (0);
@@ -167,6 +168,28 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
rep = NULL;
}
}
+
+ /*
+ * Prevent entity exponential check, not just replacement while
+ * parsing the DTD
+ * The check is potentially costly so do that only once in a thousand
+ */
+ if ((ctxt->instate == XML_PARSER_DTD) && (ctxt->nbentities > 10000) &&
+ (ctxt->nbentities % 1024 == 0)) {
+ for (i = 0;i < ctxt->inputNr;i++) {
+ consumed += ctxt->inputTab[i]->consumed +
+ (ctxt->inputTab[i]->cur - ctxt->inputTab[i]->base);
+ }
+ if (ctxt->nbentities > consumed * XML_PARSER_NON_LINEAR) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ ctxt->instate = XML_PARSER_EOF;
+ return (1);
+ }
+ consumed = 0;
+ }
+
+
+
if (replacement != 0) {
if (replacement < XML_MAX_TEXT_LENGTH)
return(0);
@@ -7927,6 +7950,9 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
xmlChar start[4];
xmlCharEncoding enc;
+ if (xmlParserEntityCheck(ctxt, 0, entity, 0))
+ return;
+
if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
((ctxt->options & XML_PARSE_NOENT) == 0) &&
((ctxt->options & XML_PARSE_DTDVALID) == 0) &&