From 0f9817c75b50a77c6aeb8f36801966fdadad229a Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Wed, 10 Jun 2020 16:34:52 +0200 Subject: [PATCH 1/2] Don't recurse into xi:include children in xmlXIncludeDoProcess Otherwise, nested xi:include nodes might result in a use-after-free if XML_PARSE_NOXINCNODE is specified. Found with libFuzzer and ASan. Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/0f9817c75b50a77c6aeb8f36801966fdadad229a] CVE: CVE-2021-3518 This patch brings in the necessary files to allow the 2nd patch that fixes the CVE to be applied. Signed-off-by: Ovidiu Panait Signed-off-by: Tony Tascioglu --- result/XInclude/fallback3.xml | 8 ++++++++ result/XInclude/fallback3.xml.err | 0 result/XInclude/fallback3.xml.rdr | 25 +++++++++++++++++++++++++ result/XInclude/fallback4.xml | 10 ++++++++++ result/XInclude/fallback4.xml.err | 0 result/XInclude/fallback4.xml.rdr | 29 +++++++++++++++++++++++++++++ test/XInclude/docs/fallback3.xml | 9 +++++++++ test/XInclude/docs/fallback4.xml | 7 +++++++ xinclude.c | 24 ++++++++++-------------- 9 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 result/XInclude/fallback3.xml create mode 100644 result/XInclude/fallback3.xml.err create mode 100644 result/XInclude/fallback3.xml.rdr create mode 100644 result/XInclude/fallback4.xml create mode 100644 result/XInclude/fallback4.xml.err create mode 100644 result/XInclude/fallback4.xml.rdr create mode 100644 test/XInclude/docs/fallback3.xml create mode 100644 test/XInclude/docs/fallback4.xml diff --git a/result/XInclude/fallback3.xml b/result/XInclude/fallback3.xml new file mode 100644 index 0000000..b423551 --- /dev/null +++ b/result/XInclude/fallback3.xml @@ -0,0 +1,8 @@ + + + +

something

+

really

+

simple

+
+
diff --git a/result/XInclude/fallback3.xml.err b/result/XInclude/fallback3.xml.err new file mode 100644 index 0000000..e69de29 diff --git a/result/XInclude/fallback3.xml.rdr b/result/XInclude/fallback3.xml.rdr new file mode 100644 index 0000000..aa2f137 --- /dev/null +++ b/result/XInclude/fallback3.xml.rdr @@ -0,0 +1,25 @@ +0 1 a 0 0 +1 14 #text 0 1 + +1 1 doc 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 something +2 15 p 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 really +2 15 p 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 simple +2 15 p 0 0 +2 14 #text 0 1 + +1 15 doc 0 0 +1 14 #text 0 1 + +0 15 a 0 0 diff --git a/result/XInclude/fallback4.xml b/result/XInclude/fallback4.xml new file mode 100644 index 0000000..9883fd5 --- /dev/null +++ b/result/XInclude/fallback4.xml @@ -0,0 +1,10 @@ + + + + +

something

+

really

+

simple

+
+ +
diff --git a/result/XInclude/fallback4.xml.err b/result/XInclude/fallback4.xml.err new file mode 100644 index 0000000..e69de29 diff --git a/result/XInclude/fallback4.xml.rdr b/result/XInclude/fallback4.xml.rdr new file mode 100644 index 0000000..628b951 --- /dev/null +++ b/result/XInclude/fallback4.xml.rdr @@ -0,0 +1,29 @@ +0 1 a 0 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 doc 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 something +2 15 p 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 really +2 15 p 0 0 +2 14 #text 0 1 + +2 1 p 0 0 +3 3 #text 0 1 simple +2 15 p 0 0 +2 14 #text 0 1 + +1 15 doc 0 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +0 15 a 0 0 diff --git a/test/XInclude/docs/fallback3.xml b/test/XInclude/docs/fallback3.xml new file mode 100644 index 0000000..0c8b6c9 --- /dev/null +++ b/test/XInclude/docs/fallback3.xml @@ -0,0 +1,9 @@ + + + + + There is no c.xml ... + + + + diff --git a/test/XInclude/docs/fallback4.xml b/test/XInclude/docs/fallback4.xml new file mode 100644 index 0000000..b500a63 --- /dev/null +++ b/test/XInclude/docs/fallback4.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/xinclude.c b/xinclude.c index 001e992..6ec5d31 100644 --- a/xinclude.c +++ b/xinclude.c @@ -2382,21 +2382,19 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { * First phase: lookup the elements in the document */ cur = tree; - if (xmlXIncludeTestNode(ctxt, cur) == 1) - xmlXIncludePreProcessNode(ctxt, cur); while ((cur != NULL) && (cur != tree->parent)) { /* TODO: need to work on entities -> stack */ - if ((cur->children != NULL) && - (cur->children->type != XML_ENTITY_DECL) && - (cur->children->type != XML_XINCLUDE_START) && - (cur->children->type != XML_XINCLUDE_END)) { - cur = cur->children; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); - } else if (cur->next != NULL) { + if (xmlXIncludeTestNode(ctxt, cur) == 1) { + xmlXIncludePreProcessNode(ctxt, cur); + } else if ((cur->children != NULL) && + (cur->children->type != XML_ENTITY_DECL) && + (cur->children->type != XML_XINCLUDE_START) && + (cur->children->type != XML_XINCLUDE_END)) { + cur = cur->children; + continue; + } + if (cur->next != NULL) { cur = cur->next; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); } else { if (cur == tree) break; @@ -2406,8 +2404,6 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { break; /* do */ if (cur->next != NULL) { cur = cur->next; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); break; /* do */ } } while (cur != NULL); -- 2.23.0