bc5a00
From 752e5f71d7cea2ca5a7e7c0b8f72ed04ce654be4 Mon Sep 17 00:00:00 2001
bc5a00
From: Nick Wellnhofer <wellnhofer@aevum.de>
bc5a00
Date: Wed, 10 Jun 2020 16:34:52 +0200
bc5a00
Subject: [PATCH 1/2] Don't recurse into xi:include children in
bc5a00
 xmlXIncludeDoProcess
bc5a00
bc5a00
Otherwise, nested xi:include nodes might result in a use-after-free
bc5a00
if XML_PARSE_NOXINCNODE is specified.
bc5a00
bc5a00
Found with libFuzzer and ASan.
bc5a00
---
bc5a00
 result/XInclude/fallback3.xml     |  8 ++++++++
bc5a00
 result/XInclude/fallback3.xml.err |  0
bc5a00
 result/XInclude/fallback3.xml.rdr | 25 +++++++++++++++++++++++++
bc5a00
 result/XInclude/fallback4.xml     | 10 ++++++++++
bc5a00
 result/XInclude/fallback4.xml.err |  0
bc5a00
 result/XInclude/fallback4.xml.rdr | 29 +++++++++++++++++++++++++++++
bc5a00
 test/XInclude/docs/fallback3.xml  |  9 +++++++++
bc5a00
 test/XInclude/docs/fallback4.xml  |  7 +++++++
bc5a00
 xinclude.c                        | 24 ++++++++++--------------
bc5a00
 9 files changed, 98 insertions(+), 14 deletions(-)
bc5a00
 create mode 100644 result/XInclude/fallback3.xml
bc5a00
 create mode 100644 result/XInclude/fallback3.xml.err
bc5a00
 create mode 100644 result/XInclude/fallback3.xml.rdr
bc5a00
 create mode 100644 result/XInclude/fallback4.xml
bc5a00
 create mode 100644 result/XInclude/fallback4.xml.err
bc5a00
 create mode 100644 result/XInclude/fallback4.xml.rdr
bc5a00
 create mode 100644 test/XInclude/docs/fallback3.xml
bc5a00
 create mode 100644 test/XInclude/docs/fallback4.xml
bc5a00
bc5a00
diff --git a/result/XInclude/fallback3.xml b/result/XInclude/fallback3.xml
bc5a00
new file mode 100644
bc5a00
index 00000000..b4235514
bc5a00
--- /dev/null
bc5a00
+++ b/result/XInclude/fallback3.xml
bc5a00
@@ -0,0 +1,8 @@
bc5a00
+
bc5a00
+
bc5a00
+    <doc xml:base="../ents/something.xml">
bc5a00
+

something

bc5a00
+

really

bc5a00
+

simple

bc5a00
+</doc>
bc5a00
+
bc5a00
diff --git a/result/XInclude/fallback3.xml.err b/result/XInclude/fallback3.xml.err
bc5a00
new file mode 100644
bc5a00
index 00000000..e69de29b
bc5a00
diff --git a/result/XInclude/fallback3.xml.rdr b/result/XInclude/fallback3.xml.rdr
bc5a00
new file mode 100644
bc5a00
index 00000000..aa2f1374
bc5a00
--- /dev/null
bc5a00
+++ b/result/XInclude/fallback3.xml.rdr
bc5a00
@@ -0,0 +1,25 @@
bc5a00
+0 1 a 0 0
bc5a00
+1 14 #text 0 1 
bc5a00
+    
bc5a00
+1 1 doc 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 something
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 really
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 simple
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+1 15 doc 0 0
bc5a00
+1 14 #text 0 1 
bc5a00
+
bc5a00
+0 15 a 0 0
bc5a00
diff --git a/result/XInclude/fallback4.xml b/result/XInclude/fallback4.xml
bc5a00
new file mode 100644
bc5a00
index 00000000..9883fd54
bc5a00
--- /dev/null
bc5a00
+++ b/result/XInclude/fallback4.xml
bc5a00
@@ -0,0 +1,10 @@
bc5a00
+
bc5a00
+
bc5a00
+    
bc5a00
+            <doc xml:base="../ents/something.xml">
bc5a00
+

something

bc5a00
+

really

bc5a00
+

simple

bc5a00
+</doc>
bc5a00
+        
bc5a00
+
bc5a00
diff --git a/result/XInclude/fallback4.xml.err b/result/XInclude/fallback4.xml.err
bc5a00
new file mode 100644
bc5a00
index 00000000..e69de29b
bc5a00
diff --git a/result/XInclude/fallback4.xml.rdr b/result/XInclude/fallback4.xml.rdr
bc5a00
new file mode 100644
bc5a00
index 00000000..628b9513
bc5a00
--- /dev/null
bc5a00
+++ b/result/XInclude/fallback4.xml.rdr
bc5a00
@@ -0,0 +1,29 @@
bc5a00
+0 1 a 0 0
bc5a00
+1 14 #text 0 1 
bc5a00
+    
bc5a00
+1 14 #text 0 1 
bc5a00
+            
bc5a00
+1 1 doc 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 something
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 really
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+2 1 p 0 0
bc5a00
+3 3 #text 0 1 simple
bc5a00
+2 15 p 0 0
bc5a00
+2 14 #text 0 1 
bc5a00
+
bc5a00
+1 15 doc 0 0
bc5a00
+1 14 #text 0 1 
bc5a00
+        
bc5a00
+1 14 #text 0 1 
bc5a00
+
bc5a00
+0 15 a 0 0
bc5a00
diff --git a/test/XInclude/docs/fallback3.xml b/test/XInclude/docs/fallback3.xml
bc5a00
new file mode 100644
bc5a00
index 00000000..0c8b6c9e
bc5a00
--- /dev/null
bc5a00
+++ b/test/XInclude/docs/fallback3.xml
bc5a00
@@ -0,0 +1,9 @@
bc5a00
+
bc5a00
+    <xi:include href="../ents/something.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
bc5a00
+        <xi:fallback>
bc5a00
+            <xi:include href="c.xml">
bc5a00
+                <xi:fallback>There is no c.xml ... </xi:fallback>
bc5a00
+            </xi:include>
bc5a00
+        </xi:fallback>
bc5a00
+    </xi:include>
bc5a00
+
bc5a00
diff --git a/test/XInclude/docs/fallback4.xml b/test/XInclude/docs/fallback4.xml
bc5a00
new file mode 100644
bc5a00
index 00000000..b500a635
bc5a00
--- /dev/null
bc5a00
+++ b/test/XInclude/docs/fallback4.xml
bc5a00
@@ -0,0 +1,7 @@
bc5a00
+
bc5a00
+    <xi:include href="c.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
bc5a00
+        <xi:fallback>
bc5a00
+            <xi:include href="../ents/something.xml"/>
bc5a00
+        </xi:fallback>
bc5a00
+    </xi:include>
bc5a00
+
bc5a00
diff --git a/xinclude.c b/xinclude.c
bc5a00
index ba850fa5..f260c1a7 100644
bc5a00
--- a/xinclude.c
bc5a00
+++ b/xinclude.c
bc5a00
@@ -2392,21 +2392,19 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
bc5a00
      * First phase: lookup the elements in the document
bc5a00
      */
bc5a00
     cur = tree;
bc5a00
-    if (xmlXIncludeTestNode(ctxt, cur) == 1)
bc5a00
-	xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
     while ((cur != NULL) && (cur != tree->parent)) {
bc5a00
 	/* TODO: need to work on entities -> stack */
bc5a00
-	if ((cur->children != NULL) &&
bc5a00
-	    (cur->children->type != XML_ENTITY_DECL) &&
bc5a00
-	    (cur->children->type != XML_XINCLUDE_START) &&
bc5a00
-	    (cur->children->type != XML_XINCLUDE_END)) {
bc5a00
-	    cur = cur->children;
bc5a00
-	    if (xmlXIncludeTestNode(ctxt, cur))
bc5a00
-		xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
-	} else if (cur->next != NULL) {
bc5a00
+        if (xmlXIncludeTestNode(ctxt, cur) == 1) {
bc5a00
+            xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
+        } else if ((cur->children != NULL) &&
bc5a00
+                   (cur->children->type != XML_ENTITY_DECL) &&
bc5a00
+                   (cur->children->type != XML_XINCLUDE_START) &&
bc5a00
+                   (cur->children->type != XML_XINCLUDE_END)) {
bc5a00
+            cur = cur->children;
bc5a00
+            continue;
bc5a00
+        }
bc5a00
+	if (cur->next != NULL) {
bc5a00
 	    cur = cur->next;
bc5a00
-	    if (xmlXIncludeTestNode(ctxt, cur))
bc5a00
-		xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
 	} else {
bc5a00
 	    if (cur == tree)
bc5a00
 	        break;
bc5a00
@@ -2416,8 +2414,6 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
bc5a00
 		    break; /* do */
bc5a00
 		if (cur->next != NULL) {
bc5a00
 		    cur = cur->next;
bc5a00
-		    if (xmlXIncludeTestNode(ctxt, cur))
bc5a00
-			xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
 		    break; /* do */
bc5a00
 		}
bc5a00
 	    } while (cur != NULL);
bc5a00
-- 
bc5a00
2.31.1
bc5a00
bc5a00
bc5a00
From 49cc4182543dba73216add4021994a81678763bd Mon Sep 17 00:00:00 2001
bc5a00
From: Nick Wellnhofer <wellnhofer@aevum.de>
bc5a00
Date: Thu, 22 Apr 2021 19:26:28 +0200
bc5a00
Subject: [PATCH 2/2] Fix user-after-free with `xmllint --xinclude --dropdtd`
bc5a00
bc5a00
The --dropdtd option can leave dangling pointers in entity reference
bc5a00
nodes. Make sure to skip these nodes when processing XIncludes.
bc5a00
bc5a00
This also avoids scanning entity declarations and even modifying
bc5a00
them inadvertently during XInclude processing.
bc5a00
bc5a00
Move from a block list to an allow list approach to avoid descending
bc5a00
into other node types that can't contain elements.
bc5a00
bc5a00
Fixes #237.
bc5a00
---
bc5a00
 xinclude.c | 5 ++---
bc5a00
 1 file changed, 2 insertions(+), 3 deletions(-)
bc5a00
bc5a00
diff --git a/xinclude.c b/xinclude.c
bc5a00
index f260c1a7..d7648529 100644
bc5a00
--- a/xinclude.c
bc5a00
+++ b/xinclude.c
bc5a00
@@ -2397,9 +2397,8 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
bc5a00
         if (xmlXIncludeTestNode(ctxt, cur) == 1) {
bc5a00
             xmlXIncludePreProcessNode(ctxt, cur);
bc5a00
         } else if ((cur->children != NULL) &&
bc5a00
-                   (cur->children->type != XML_ENTITY_DECL) &&
bc5a00
-                   (cur->children->type != XML_XINCLUDE_START) &&
bc5a00
-                   (cur->children->type != XML_XINCLUDE_END)) {
bc5a00
+                   ((cur->type == XML_DOCUMENT_NODE) ||
bc5a00
+                    (cur->type == XML_ELEMENT_NODE))) {
bc5a00
             cur = cur->children;
bc5a00
             continue;
bc5a00
         }
bc5a00
-- 
bc5a00
2.31.1
bc5a00