|
@@ -0,0 +1,186 @@
|
|
|
+From a89ed49b681fb4299120154ce0d6ca38e9abe482 Mon Sep 17 00:00:00 2001
|
|
|
+From: Nick Wellnhofer <wellnhofer@aevum.de>
|
|
|
+Date: Fri, 4 Jul 2025 14:28:26 +0200
|
|
|
+Subject: [PATCH] schematron: Fix memory safety issues in
|
|
|
+ xmlSchematronReportOutput
|
|
|
+
|
|
|
+Fix use-after-free (CVE-2025-49794) and type confusion (CVE-2025-49796)
|
|
|
+in xmlSchematronReportOutput.
|
|
|
+
|
|
|
+Fixes #931.
|
|
|
+Fixes #933.
|
|
|
+
|
|
|
+Upstream: https://gitlab.gnome.org/GNOME/libxml2/-/commit/71e1e8af5ee46dad1b57bb96cfbf1c3ad21fbd7b
|
|
|
+CVE: CVE-2025-49794 CVE-2025-49796
|
|
|
+Signed-off-by: Tim Soubry <tim.soubry@mind.be>
|
|
|
+---
|
|
|
+ result/schematron/cve-2025-49794_0.err | 2 ++
|
|
|
+ result/schematron/cve-2025-49796_0.err | 2 ++
|
|
|
+ schematron.c | 49 ++++++++++++++------------
|
|
|
+ test/schematron/cve-2025-49794.sct | 10 ++++++
|
|
|
+ test/schematron/cve-2025-49794_0.xml | 6 ++++
|
|
|
+ test/schematron/cve-2025-49796.sct | 9 +++++
|
|
|
+ test/schematron/cve-2025-49796_0.xml | 3 ++
|
|
|
+ 7 files changed, 58 insertions(+), 23 deletions(-)
|
|
|
+ create mode 100644 result/schematron/cve-2025-49794_0.err
|
|
|
+ create mode 100644 result/schematron/cve-2025-49796_0.err
|
|
|
+ create mode 100644 test/schematron/cve-2025-49794.sct
|
|
|
+ create mode 100644 test/schematron/cve-2025-49794_0.xml
|
|
|
+ create mode 100644 test/schematron/cve-2025-49796.sct
|
|
|
+ create mode 100644 test/schematron/cve-2025-49796_0.xml
|
|
|
+
|
|
|
+diff --git a/result/schematron/cve-2025-49794_0.err b/result/schematron/cve-2025-49794_0.err
|
|
|
+new file mode 100644
|
|
|
+index 00000000..57752310
|
|
|
+--- /dev/null
|
|
|
++++ b/result/schematron/cve-2025-49794_0.err
|
|
|
+@@ -0,0 +1,2 @@
|
|
|
++./test/schematron/cve-2025-49794_0.xml:2: element boo0: schematron error : /librar0/boo0 line 2:
|
|
|
++./test/schematron/cve-2025-49794_0.xml fails to validate
|
|
|
+diff --git a/result/schematron/cve-2025-49796_0.err b/result/schematron/cve-2025-49796_0.err
|
|
|
+new file mode 100644
|
|
|
+index 00000000..bf875ee0
|
|
|
+--- /dev/null
|
|
|
++++ b/result/schematron/cve-2025-49796_0.err
|
|
|
+@@ -0,0 +1,2 @@
|
|
|
++./test/schematron/cve-2025-49796_0.xml:2: element boo0: schematron error : /librar0/boo0 line 2:
|
|
|
++./test/schematron/cve-2025-49796_0.xml fails to validate
|
|
|
+diff --git a/schematron.c b/schematron.c
|
|
|
+index 1de25deb..426300c8 100644
|
|
|
+--- a/schematron.c
|
|
|
++++ b/schematron.c
|
|
|
+@@ -1414,27 +1414,15 @@ exit:
|
|
|
+ * *
|
|
|
+ ************************************************************************/
|
|
|
+
|
|
|
+-static xmlNodePtr
|
|
|
++static xmlXPathObjectPtr
|
|
|
+ xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
|
|
|
+ xmlNodePtr cur, const xmlChar *xpath) {
|
|
|
+- xmlNodePtr node = NULL;
|
|
|
+- xmlXPathObjectPtr ret;
|
|
|
+-
|
|
|
+ if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
|
|
|
+ return(NULL);
|
|
|
+
|
|
|
+ ctxt->xctxt->doc = cur->doc;
|
|
|
+ ctxt->xctxt->node = cur;
|
|
|
+- ret = xmlXPathEval(xpath, ctxt->xctxt);
|
|
|
+- if (ret == NULL)
|
|
|
+- return(NULL);
|
|
|
+-
|
|
|
+- if ((ret->type == XPATH_NODESET) &&
|
|
|
+- (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
|
|
|
+- node = ret->nodesetval->nodeTab[0];
|
|
|
+-
|
|
|
+- xmlXPathFreeObject(ret);
|
|
|
+- return(node);
|
|
|
++ return(xmlXPathEval(xpath, ctxt->xctxt));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+@@ -1480,25 +1468,40 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
|
|
|
+ (child->type == XML_CDATA_SECTION_NODE))
|
|
|
+ ret = xmlStrcat(ret, child->content);
|
|
|
+ else if (IS_SCHEMATRON(child, "name")) {
|
|
|
++ xmlXPathObject *obj = NULL;
|
|
|
+ xmlChar *path;
|
|
|
+
|
|
|
+ path = xmlGetNoNsProp(child, BAD_CAST "path");
|
|
|
+
|
|
|
+ node = cur;
|
|
|
+ if (path != NULL) {
|
|
|
+- node = xmlSchematronGetNode(ctxt, cur, path);
|
|
|
+- if (node == NULL)
|
|
|
+- node = cur;
|
|
|
++ obj = xmlSchematronGetNode(ctxt, cur, path);
|
|
|
++ if ((obj != NULL) &&
|
|
|
++ (obj->type == XPATH_NODESET) &&
|
|
|
++ (obj->nodesetval != NULL) &&
|
|
|
++ (obj->nodesetval->nodeNr > 0))
|
|
|
++ node = obj->nodesetval->nodeTab[0];
|
|
|
+ xmlFree(path);
|
|
|
+ }
|
|
|
+
|
|
|
+- if ((node->ns == NULL) || (node->ns->prefix == NULL))
|
|
|
+- ret = xmlStrcat(ret, node->name);
|
|
|
+- else {
|
|
|
+- ret = xmlStrcat(ret, node->ns->prefix);
|
|
|
+- ret = xmlStrcat(ret, BAD_CAST ":");
|
|
|
+- ret = xmlStrcat(ret, node->name);
|
|
|
++ switch (node->type) {
|
|
|
++ case XML_ELEMENT_NODE:
|
|
|
++ case XML_ATTRIBUTE_NODE:
|
|
|
++ if ((node->ns == NULL) || (node->ns->prefix == NULL))
|
|
|
++ ret = xmlStrcat(ret, node->name);
|
|
|
++ else {
|
|
|
++ ret = xmlStrcat(ret, node->ns->prefix);
|
|
|
++ ret = xmlStrcat(ret, BAD_CAST ":");
|
|
|
++ ret = xmlStrcat(ret, node->name);
|
|
|
++ }
|
|
|
++ break;
|
|
|
++
|
|
|
++ /* TODO: handle other node types */
|
|
|
++ default:
|
|
|
++ break;
|
|
|
+ }
|
|
|
++
|
|
|
++ xmlXPathFreeObject(obj);
|
|
|
+ } else if (IS_SCHEMATRON(child, "value-of")) {
|
|
|
+ xmlChar *select;
|
|
|
+ xmlXPathObjectPtr eval;
|
|
|
+diff --git a/test/schematron/cve-2025-49794.sct b/test/schematron/cve-2025-49794.sct
|
|
|
+new file mode 100644
|
|
|
+index 00000000..7fc9ee3d
|
|
|
+--- /dev/null
|
|
|
++++ b/test/schematron/cve-2025-49794.sct
|
|
|
+@@ -0,0 +1,10 @@
|
|
|
++<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
|
|
|
++ <sch:pattern id="">
|
|
|
++ <sch:rule context="boo0">
|
|
|
++ <sch:report test="not(0)">
|
|
|
++ <sch:name path="	e|namespace::*|e"/>
|
|
|
++ </sch:report>
|
|
|
++ <sch:report test="0"></sch:report>
|
|
|
++ </sch:rule>
|
|
|
++ </sch:pattern>
|
|
|
++</sch:schema>
|
|
|
+diff --git a/test/schematron/cve-2025-49794_0.xml b/test/schematron/cve-2025-49794_0.xml
|
|
|
+new file mode 100644
|
|
|
+index 00000000..debc64ba
|
|
|
+--- /dev/null
|
|
|
++++ b/test/schematron/cve-2025-49794_0.xml
|
|
|
+@@ -0,0 +1,6 @@
|
|
|
++<librar0>
|
|
|
++ <boo0 t="">
|
|
|
++ <author></author>
|
|
|
++ </boo0>
|
|
|
++ <ins></ins>
|
|
|
++</librar0>
|
|
|
+diff --git a/test/schematron/cve-2025-49796.sct b/test/schematron/cve-2025-49796.sct
|
|
|
+new file mode 100644
|
|
|
+index 00000000..e9702d75
|
|
|
+--- /dev/null
|
|
|
++++ b/test/schematron/cve-2025-49796.sct
|
|
|
+@@ -0,0 +1,9 @@
|
|
|
++<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
|
|
|
++ <sch:pattern id="">
|
|
|
++ <sch:rule context="boo0">
|
|
|
++ <sch:report test="not(0)">
|
|
|
++ <sch:name path="/"/>
|
|
|
++ </sch:report>
|
|
|
++ </sch:rule>
|
|
|
++ </sch:pattern>
|
|
|
++</sch:schema>
|
|
|
+diff --git a/test/schematron/cve-2025-49796_0.xml b/test/schematron/cve-2025-49796_0.xml
|
|
|
+new file mode 100644
|
|
|
+index 00000000..be33c4ec
|
|
|
+--- /dev/null
|
|
|
++++ b/test/schematron/cve-2025-49796_0.xml
|
|
|
+@@ -0,0 +1,3 @@
|
|
|
++<librar0>
|
|
|
++ <boo0/>
|
|
|
++</librar0>
|
|
|
+--
|
|
|
+2.39.5
|
|
|
+
|