From 0f9817c75b50a77c6aeb8f36801966fdadad229a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
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 <ovidiu.panait@windriver.com>
Signed-off-by: Tony Tascioglu <tony.tascioglu@windriver.com>
---
 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 @@
+<?xml version="1.0"?>
+<a>
+    <doc xml:base="../ents/something.xml">
+<p>something</p>
+<p>really</p>
+<p>simple</p>
+</doc>
+</a>
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 @@
+<?xml version="1.0"?>
+<a>
+    
+            <doc xml:base="../ents/something.xml">
+<p>something</p>
+<p>really</p>
+<p>simple</p>
+</doc>
+        
+</a>
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 @@
+<a>
+    <xi:include href="../ents/something.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
+        <xi:fallback>
+            <xi:include href="c.xml">
+                <xi:fallback>There is no c.xml ... </xi:fallback>
+            </xi:include>
+        </xi:fallback>
+    </xi:include>
+</a>
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 @@
+<a>
+    <xi:include href="c.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
+        <xi:fallback>
+            <xi:include href="../ents/something.xml"/>
+        </xi:fallback>
+    </xi:include>
+</a>
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

