libxml2: Fix CVE-2026-86144

This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].

[1] https://github.com/GNOME/libxml2/commit/b63cd517afecb76582dd9488c55e54ceaf50de61
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-86144

(From OE-Core rev: 4b03cdc9cab9419ba55f0b0baf10c04412d690fa)

Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Hetvi Thakar authored and Paul Barker committed 2026-10-19 09:03:18 +01:00
1 parent ef8931543a
commit 178e675500
2 files changed
+226

No files matched your search

@@ -0,0 +1,225 @@
From 8d0c6eb94f8a32a49e3c9122a6da82c519198063 Mon Sep 17 00:00:00 2001
From: Ruben Thijssen <ruben.thijssen@cba.com.au>
Date: Fri, 15 May 2026 15:42:18 +1000
Subject: [PATCH] fix(xinclude): propagate parseFlags in xmlXIncludeProcess and
xmlXIncludeProcessTree
CVE: CVE-2026-86144
Upstream-Status: Backport [https://github.com/GNOME/libxml2/commit/b63cd517afecb76582dd9488c55e54ceaf50de61]
Backport Changes:
- Use xmlLoadExternalEntity() with xmlCtxtUseOptions() because Scarthgap
2.12.10 predates xmlLoadResource() and resource-loader callbacks.
- Adapt the regression tests for 2.12.10 by using the global structured-error
handler, matching 2.12.10 loader network-entity diagnostics, and restoring
the test handler after xmlXIncludeProcess().
- Omit the upstream XML_IO_NETWORK_ATTEMPT filter because the 2.12.10
xmlLoadExternalEntity() path has no corresponding post-load error-filtering
block.
- Add a parser-context allocation guard because the target version can return
NULL from xmlNewParserCtxt().
(cherry picked from commit b63cd517afecb76582dd9488c55e54ceaf50de61)
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
---
result/XInclude/issue1120-1.xml | 4 ++
result/XInclude/issue1120-1.xml.err | 1 +
result/XInclude/issue1120-2.xml | 4 ++
result/XInclude/issue1120-2.xml.err | 1 +
runtest.c | 75 +++++++++++++++++++++++++
test/XInclude/issue1120/issue1120-1.xml | 6 ++
test/XInclude/issue1120/issue1120-2.xml | 6 ++
xinclude.c | 9 ++-
8 files changed, 104 insertions(+), 2 deletions(-)
create mode 100644 result/XInclude/issue1120-1.xml
create mode 100644 result/XInclude/issue1120-1.xml.err
create mode 100644 result/XInclude/issue1120-2.xml
create mode 100644 result/XInclude/issue1120-2.xml.err
create mode 100644 test/XInclude/issue1120/issue1120-1.xml
create mode 100644 test/XInclude/issue1120/issue1120-2.xml
diff --git a/result/XInclude/issue1120-1.xml b/result/XInclude/issue1120-1.xml
new file mode 100644
index 00000000..5d83cc96
--- /dev/null
+++ b/result/XInclude/issue1120-1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<doc xmlns:xi="http://www.w3.org/2001/XInclude">
+ Network access is not allowed
+</doc>
diff --git a/result/XInclude/issue1120-1.xml.err b/result/XInclude/issue1120-1.xml.err
new file mode 100644
index 00000000..c134bed1
--- /dev/null
+++ b/result/XInclude/issue1120-1.xml.err
@@ -0,0 +1 @@
+I/O error : Attempt to load network entity http://example.invalid/file.txt
diff --git a/result/XInclude/issue1120-2.xml b/result/XInclude/issue1120-2.xml
new file mode 100644
index 00000000..af5bde91
--- /dev/null
+++ b/result/XInclude/issue1120-2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<doc xmlns:xi="http://www.w3.org/2001/XInclude">
+ <p>Network access is not allowed</p>
+</doc>
diff --git a/result/XInclude/issue1120-2.xml.err b/result/XInclude/issue1120-2.xml.err
new file mode 100644
index 00000000..051f5928
--- /dev/null
+++ b/result/XInclude/issue1120-2.xml.err
@@ -0,0 +1 @@
+I/O error : Attempt to load network entity http://example.invalid/file.xml
diff --git a/runtest.c b/runtest.c
index e91e2dfd..297cb5e2 100644
--- a/runtest.c
+++ b/runtest.c
@@ -2444,6 +2444,75 @@ noentParseTest(const char *filename, const char *result,
return(res);
}
+#ifdef LIBXML_XINCLUDE_ENABLED
+/**
+ * Parse a file and run xmlXIncludeProcess() to verify that doc->parseFlags
+ * is propagated properly.
+ *
+ * @param filename the file to parse
+ * @param result the file with expected result
+ * @param err the file with error messages
+ * @returns 0 in case of success, an error code otherwise
+ */
+static int
+xincludeProcessTest(const char *filename, const char *result, const char *err,
+ int options) {
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc;
+ xmlChar *base = NULL;
+ int size, res;
+ int ret = 0;
+
+ nb_tests++;
+
+ /* Create a new parser context */
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL)
+ return(-1);
+
+ /* Load the data from `filename` into a parser context */
+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+ xmlFreeParserCtxt(ctxt);
+
+ /* Check if `doc` was created successfully */
+ if (doc == NULL) {
+ testErrorHandler(NULL, "%s : failed to parse\n", filename);
+ return(-1);
+ }
+
+ /*
+ * Run xmlXIncludeProcess() with a structured error handler to check that
+ * the parse flags are propagated.
+ */
+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+ xmlXIncludeProcess(doc);
+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+
+ /* Check the result and for any errors */
+ if (result) {
+ xmlDocDumpMemory(doc, &base, &size);
+ res = compareFileMem(result, (char *) base, size);
+ xmlFree(base);
+ if (res != 0) {
+ fprintf(stderr, "Result for %s failed in %s\n", filename, result);
+ ret = -1;
+ }
+ }
+
+ if ((ret == 0) && (err != NULL)) {
+ res = compareFileMem(err, testErrors, testErrorsSize);
+ if (res != 0) {
+ fprintf(stderr, "Error for %s failed\n", filename);
+ ret = -1;
+ }
+ }
+
+ xmlFreeDoc(doc);
+ return(ret);
+}
+#endif
+
/**
* errParseTest:
* @filename: the file to parse
@@ -5134,6 +5203,12 @@ testDesc testDescriptions[] = {
{ "XInclude regression tests without reader",
errParseTest, "./test/XInclude/without-reader/*", "result/XInclude/", "",
".err", XML_PARSE_XINCLUDE },
+ { "XInclude issue1120 regression tests",
+ errParseTest, "./test/XInclude/issue1120/*", "result/XInclude/", "",
+ ".err", XML_PARSE_XINCLUDE | XML_PARSE_NONET },
+ { "XInclude xmlXIncludeProcess() issue1120 regression tests",
+ xincludeProcessTest, "./test/XInclude/issue1120/*", "result/XInclude/",
+ "", ".err", XML_PARSE_NONET },
#endif
#ifdef LIBXML_XPATH_ENABLED
#ifdef LIBXML_DEBUG_ENABLED
diff --git a/test/XInclude/issue1120/issue1120-1.xml b/test/XInclude/issue1120/issue1120-1.xml
new file mode 100644
index 00000000..b0b8feef
--- /dev/null
+++ b/test/XInclude/issue1120/issue1120-1.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<doc xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="http://example.invalid/file.txt" parse="text">
+ <xi:fallback>Network access is not allowed</xi:fallback>
+ </xi:include>
+</doc>
diff --git a/test/XInclude/issue1120/issue1120-2.xml b/test/XInclude/issue1120/issue1120-2.xml
new file mode 100644
index 00000000..b4c9fe5e
--- /dev/null
+++ b/test/XInclude/issue1120/issue1120-2.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<doc xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="http://example.invalid/file.xml">
+ <xi:fallback><p>Network access is not allowed</p></xi:fallback>
+ </xi:include>
+</doc>
diff --git a/xinclude.c b/xinclude.c
index b6581558..0d57f5a1 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -1688,6 +1688,11 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* Load it.
*/
pctxt = xmlNewParserCtxt();
+ if (pctxt == NULL) {
+ xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
+ goto error;
+ }
+ xmlCtxtUseOptions(pctxt, ctxt->parseFlags);
inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
if(inputStream == NULL)
goto error;
@@ -2416,7 +2421,7 @@ xmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {
*/
int
xmlXIncludeProcess(xmlDocPtr doc) {
- return(xmlXIncludeProcessFlags(doc, 0));
+ return(xmlXIncludeProcessFlags(doc, doc ? doc->parseFlags : 0));
}
/**
@@ -2461,7 +2466,7 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
*/
int
xmlXIncludeProcessTree(xmlNodePtr tree) {
- return(xmlXIncludeProcessTreeFlags(tree, 0));
+ return(xmlXIncludeProcessTreeFlags(tree, (tree && tree->doc) ? tree->doc->parseFlags : 0));
}
/**
@@ -38,6 +38,7 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20130923.tar;subdir=${BP};name=testt
file://CVE-2026-86141.patch \
file://CVE-2026-86142.patch \
file://CVE-2026-86143.patch \
file://CVE-2026-86144.patch \
"
SRC_URI[archive.sha256sum] = "c3d8c0c34aa39098f66576fe51969db12a5100b956233dc56506f7a8679be995"