Package: release.debian.org Severity: normal Tags: trixie moreinfo X-Debbugs-Cc: [email protected], [email protected] Control: affects -1 + src:libxml2.9 User: [email protected] Usertags: pu
[ Reason ]
Fix <no-dsa> issues CVE-2026-0989, CVE-2026-0990 and CVE-2026-0992,
<unimportant> issues CVE-2025-8732 and CVE-2026-1757, as well as some
more security-related issues (memory leaks, use after free and stack
overflow issues) for which no CVE ID was assigned (yet).
[ Impact ]
Users will remain vulnerable to the afformentioned issues, and will
regress when upgrading upgrading (a fix will be uploaded to Bullseye LTS
shortly).
[ Tests ]
Manually checked each POC supplied in the upstream bug tracker, and ran
the extended test suite (skipped at build time and in the autopkgtests)
included the new unit tests from the backported changes.
[ Risks ]
Low risk: the backported changes are targetted and come from upstream's
2.15 branch, and for the most part apply cleanly.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in stable
[x] the issue is verified as fixed in unstable
[ Changes ]
* Fix CVE-2026-0989: Specially crafted or overly complex schemas can cause
excessive recursion during parsing, which may lead to stack exhaustion and
application crashes. The parser now enforces a limit on inclusion depth
when resolving nested `<include>` directives; the limit defaults to 1000
and can be modified at runtime with the env variable `RNG_INCLUDE_LIMIT`.
* Fix CVE-2026-0990: `xmlCatalogXMLResolveURI()` will recurse infinitely if
a catalog has a URI delegate referencing itself, eventually resulting in a
call stack overflow.
* Fix CVE-2026-0992: Denial of Service vulnerability due to uncontrolled
resource consumption when processing XML catalogs containing repeated
`<nextCatalog>` elements pointing to the same downstream catalog.
* Fix CVE-2025-8732: When a catalog file contains a CATALOG directive
pointing to itself, `xmlExpandCatalog()` and `xmlParseSGMLCatalog()`
recursively call each other without bounds until stack overflow.
* Fix CVE-2026-1757: Memory leak issue in the command parsing logic of the
xmllint interactive shell.
* Fix unit tests for CVE-2025-49794 and -49796.
* Backport some more upstream changes from v2.15.2:
+ Fix memory leak of prefix in `xmlTextWriterStartElementNS()`.
+ Mitigate use-after-free issue in `xmlRelaxNGValidateValue()`.
+ Fix memory leak in `xmlTextWriterStartAttributeNS()`.
+ Schematron: Fix additional memory leaks on error paths.
+ Catalog: Fix stack overflow from self-referencing SGML CATALOG entries.
* Add d/salsa-ci.yml for Salsa CI.
--
Guilhem.
diffstat for libxml2-2.12.7+dfsg+really2.9.14 libxml2-2.12.7+dfsg+really2.9.14 changelog | 32 + libxml2.symbols | 2 patches/0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch | 21 patches/0035-testcatalog-Add-new-tests-for-catalog.c.patch | 306 +++++++++ patches/0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch | 22 patches/0038-fix-memory-leak-in-issue-1054.patch | 44 + patches/0039-schematron-fix-additional-memory-leaks-on-error-path.patch | 51 + patches/0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch | 45 + patches/CVE-2025-49794_49796.patch | 31 - patches/CVE-2025-8732.patch | 149 ++++ patches/CVE-2026-0989.patch | 308 ++++++++++ patches/CVE-2026-0990.patch | 74 ++ patches/CVE-2026-0992/01-4af23b523.patch | 47 + patches/CVE-2026-0992/02-096402c94.patch | 31 + patches/CVE-2026-1757.patch | 34 + patches/series | 12 salsa-ci.yml | 8 17 files changed, 1213 insertions(+), 4 deletions(-) diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/changelog libxml2-2.12.7+dfsg+really2.9.14/debian/changelog --- libxml2-2.12.7+dfsg+really2.9.14/debian/changelog 2025-10-11 14:55:59.000000000 +0200 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/changelog 2026-06-07 19:02:23.000000000 +0200 @@ -1,3 +1,35 @@ +libxml2 (2.12.7+dfsg+really2.9.14-2.1+deb13u3) trixie; urgency=high + + * Non-maintainer upload. + * Fix CVE-2026-0989: Specially crafted or overly complex schemas can cause + excessive recursion during parsing, which may lead to stack exhaustion and + application crashes. The parser now enforces a limit on inclusion depth + when resolving nested `<include>` directives; the limit defaults to 1000 + and can be modified at runtime with the env variable `RNG_INCLUDE_LIMIT`. + (Closes: #1125691) + * Fix CVE-2026-0990: `xmlCatalogXMLResolveURI()` will recurse infinitely if + a catalog has a URI delegate referencing itself, eventually resulting in a + call stack overflow. (Closes: #1125695) + * Fix CVE-2026-0992: Denial of Service vulnerability due to uncontrolled + resource consumption when processing XML catalogs containing repeated + `<nextCatalog>` elements pointing to the same downstream catalog. + (Closes: #1125696) + * Fix CVE-2025-8732: When a catalog file contains a CATALOG directive + pointing to itself, `xmlExpandCatalog()` and `xmlParseSGMLCatalog()` + recursively call each other without bounds until stack overflow. + * Fix CVE-2026-1757: Memory leak issue in the command parsing logic of the + xmllint interactive shell. + * Fix unit tests for CVE-2025-49794 and -49796. + * Backport some more upstream changes from v2.15.2: + + Fix memory leak of prefix in `xmlTextWriterStartElementNS()`. + + Mitigate use-after-free issue in `xmlRelaxNGValidateValue()`. + + Fix memory leak in `xmlTextWriterStartAttributeNS()`. + + Schematron: Fix additional memory leaks on error paths. + + Catalog: Fix stack overflow from self-referencing SGML CATALOG entries. + * Add d/salsa-ci.yml for Salsa CI. + + -- Guilhem Moulin <[email protected]> Sun, 07 Jun 2026 19:02:23 +0200 + libxml2 (2.12.7+dfsg+really2.9.14-2.1+deb13u2) trixie; urgency=high * Non-maintainer upload. diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/libxml2.symbols libxml2-2.12.7+dfsg+really2.9.14/debian/libxml2.symbols --- libxml2-2.12.7+dfsg+really2.9.14/debian/libxml2.symbols 2025-10-11 14:55:59.000000000 +0200 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/libxml2.symbols 2026-06-07 19:02:23.000000000 +0200 @@ -138,6 +138,7 @@ xmlBufWriteQuotedString@Base 2.9.0 xmlBufferDetach@LIBXML2_2.8.0 2.8.0 xmlBuildRelativeURI@LIBXML2_2.6.11 2.8.0 + xmlCatalogDumpDoc@Base 2.12.7+dfsg+really2.9.14-2.1+deb13u3~ xmlCharEncFirstLineInput@Base 2.9.0 xmlCharEncFirstLineInt@Base 2.7.4 xmlCharEncInput@Base 2.9.0 @@ -158,6 +159,7 @@ xmlParserInputBufferCreateFilenameDefault@LIBXML2_2.6.11 2.8.0 xmlParserInputBufferCreateFilenameValue@LIBXML2_2.6.11 2.8.0 xmlPopOutputCallbacks@LIBXML2_2.9.11 2.9.11 + xmlRelaxParserSetIncLImit@Base 2.12.7+dfsg+really2.9.14-2.1+deb13u3~ xmlSchemaCollapseString@LIBXML2_2.6.11 2.8.0 xmlSchemaFreeWildcard@LIBXML2_2.6.11 2.8.0 xmlSchemaGetBuiltInListSimpleTypeItemType@LIBXML2_2.6.11 2.8.0 diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,21 @@ +From: Niels Dossche <[email protected]> +Date: Thu, 4 Sep 2025 21:13:24 +0200 +Subject: Fix memory leak of prefix in xmlTextWriterStartElementNS() + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/7d138310f1d4f006d490e29c72168c8ede3a020a +--- + xmlwriter.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xmlwriter.c b/xmlwriter.c +index 58445c8..49b3012 100644 +--- a/xmlwriter.c ++++ b/xmlwriter.c +@@ -1095,6 +1095,7 @@ xmlTextWriterStartElementNS(xmlTextWriterPtr writer, + if (p->uri == 0) { + xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, + "xmlTextWriterStartElementNS : out of memory!\n"); ++ xmlFree(p->prefix); + xmlFree(p); + return -1; + } diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0035-testcatalog-Add-new-tests-for-catalog.c.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0035-testcatalog-Add-new-tests-for-catalog.c.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0035-testcatalog-Add-new-tests-for-catalog.c.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0035-testcatalog-Add-new-tests-for-catalog.c.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,306 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Fri, 19 Dec 2025 12:27:54 +0100 +Subject: testcatalog: Add new tests for catalog.c + +Adds a new test program to run specific tests related to catalog +parsing. + +This initial version includes a couple of tests, the first one to check +the infinite recursion detection related to: +https://gitlab.gnome.org/GNOME/libxml2/-/issues/1018. + +The second one tests the nextCatalog element repeated parsing, related +to: +https://gitlab.gnome.org/GNOME/libxml2/-/issues/1019 +https://gitlab.gnome.org/GNOME/libxml2/-/issues/1040 + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/f14c733327f163b49a632f03d05a58c119ed7e57 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1018 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1019 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1040 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-0990 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-0992 +--- + Makefile.am | 8 ++- + catalog.c | 63 +++++++++++++++------- + include/libxml/catalog.h | 2 + + test/catalogs/catalog-recursive.xml | 3 ++ + test/catalogs/repeated-next-catalog.xml | 10 ++++ + testcatalog.c | 96 +++++++++++++++++++++++++++++++++ + 6 files changed, 161 insertions(+), 21 deletions(-) + create mode 100644 test/catalogs/catalog-recursive.xml + create mode 100644 test/catalogs/repeated-next-catalog.xml + create mode 100644 testcatalog.c + +diff --git a/Makefile.am b/Makefile.am +index 7917b59..17b2496 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -12,7 +12,7 @@ AM_CFLAGS = $(EXTRA_CFLAGS) $(THREAD_CFLAGS) $(Z_CFLAGS) $(LZMA_CFLAGS) + + check_PROGRAMS=testSchemas testRelax testSAX testHTML testXPath testURI \ + testThreads testC14N testAutomata testRegexp \ +- testReader testapi testModule runtest runsuite testchar \ ++ testReader testapi testcatalog testModule runtest runsuite testchar \ + testdict runxmlconf testrecurse testlimits + + bin_PROGRAMS = xmllint xmlcatalog +@@ -81,6 +81,10 @@ testlimits_LDFLAGS = + testlimits_DEPENDENCIES = $(DEPS) + testlimits_LDADD= $(BASE_THREAD_LIBS) $(RDL_LIBS) $(LDADDS) + ++testcatalog_SOURCES=testcatalog.c ++testcatalog_DEPENDENCIES = $(DEPS) ++testcatalog_LDADD= $(LDADDS) ++ + testchar_SOURCES=testchar.c + testchar_LDFLAGS = + testchar_DEPENDENCIES = $(DEPS) +@@ -198,7 +202,7 @@ runxmlconf_LDADD= $(LDADDS) + #testOOM_DEPENDENCIES = $(DEPS) + #testOOM_LDADD= $(LDADDS) + +-runtests: runtest$(EXEEXT) testrecurse$(EXEEXT) testapi$(EXEEXT) \ ++runtests: runtest$(EXEEXT) testrecurse$(EXEEXT) testapi$(EXEEXT) testcatalog$(EXEEXT) \ + testchar$(EXEEXT) testdict$(EXEEXT) runxmlconf$(EXEEXT) + [ -d test ] || $(LN_S) $(srcdir)/test . + [ -d result ] || $(LN_S) $(srcdir)/result . +diff --git a/catalog.c b/catalog.c +index c211812..df97a67 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -658,43 +658,54 @@ static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog, + } + } + +-static int +-xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) { +- int ret; +- xmlDocPtr doc; ++static xmlDocPtr ++xmlDumpXMLCatalogToDoc(xmlCatalogEntryPtr catal) { + xmlNsPtr ns; + xmlDtdPtr dtd; + xmlNodePtr catalog; +- xmlOutputBufferPtr buf; ++ xmlDocPtr doc = xmlNewDoc(NULL); ++ if (doc == NULL) { ++ return(NULL); ++ } + +- /* +- * Rebuild a catalog +- */ +- doc = xmlNewDoc(NULL); +- if (doc == NULL) +- return(-1); + dtd = xmlNewDtd(doc, BAD_CAST "catalog", +- BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN", +-BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"); ++ BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN", ++ BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"); + + xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd); + + ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL); + if (ns == NULL) { +- xmlFreeDoc(doc); +- return(-1); ++ xmlFreeDoc(doc); ++ return(NULL); + } + catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL); + if (catalog == NULL) { +- xmlFreeNs(ns); +- xmlFreeDoc(doc); +- return(-1); ++ xmlFreeDoc(doc); ++ xmlFreeNs(ns); ++ return(NULL); + } + catalog->nsDef = ns; + xmlAddChild((xmlNodePtr) doc, catalog); +- + xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL); + ++ return(doc); ++} ++ ++static int ++xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) { ++ int ret; ++ xmlDocPtr doc; ++ xmlOutputBufferPtr buf; ++ ++ /* ++ * Rebuild a catalog ++ */ ++ doc = xmlDumpXMLCatalogToDoc(catal); ++ if (doc == NULL) { ++ return(-1); ++ } ++ + /* + * reserialize it + */ +@@ -3441,6 +3452,20 @@ xmlCatalogDump(FILE *out) { + + xmlACatalogDump(xmlDefaultCatalog, out); + } ++ ++/** ++ * Dump all the global catalog content as a xmlDoc ++ * This function is just for testing/debugging purposes ++ * ++ * @returns The catalog as xmlDoc or NULL if failed, it must be freed by the caller. ++ */ ++xmlDocPtr ++xmlCatalogDumpDoc(void) { ++ if (!xmlCatalogInitialized) ++ xmlInitializeCatalog(); ++ ++ return xmlDumpXMLCatalogToDoc(xmlDefaultCatalog->xml); ++} + #endif /* LIBXML_OUTPUT_ENABLED */ + + /** +diff --git a/include/libxml/catalog.h b/include/libxml/catalog.h +index 26b178d..a507a87 100644 +--- a/include/libxml/catalog.h ++++ b/include/libxml/catalog.h +@@ -119,6 +119,8 @@ XMLPUBFUN void XMLCALL + #ifdef LIBXML_OUTPUT_ENABLED + XMLPUBFUN void XMLCALL + xmlCatalogDump (FILE *out); ++XMLPUBFUN xmlDocPtr ++ xmlCatalogDumpDoc (void); + #endif /* LIBXML_OUTPUT_ENABLED */ + XMLPUBFUN xmlChar * XMLCALL + xmlCatalogResolve (const xmlChar *pubID, +diff --git a/test/catalogs/catalog-recursive.xml b/test/catalogs/catalog-recursive.xml +new file mode 100644 +index 0000000..3b3d03f +--- /dev/null ++++ b/test/catalogs/catalog-recursive.xml +@@ -0,0 +1,3 @@ ++<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> ++ <delegateURI uriStartString="/foo" catalog="catalog-recursive.xml"/> ++</catalog> +diff --git a/test/catalogs/repeated-next-catalog.xml b/test/catalogs/repeated-next-catalog.xml +new file mode 100644 +index 0000000..76d34c3 +--- /dev/null ++++ b/test/catalogs/repeated-next-catalog.xml +@@ -0,0 +1,10 @@ ++<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> ++ <nextCatalog catalog="registry.xml"/> ++ <nextCatalog catalog="registry.xml"/> ++ <nextCatalog catalog="./registry.xml"/> ++ <nextCatalog catalog="././registry.xml"/> ++ <nextCatalog catalog="./././registry.xml"/> ++ <nextCatalog catalog="./../catalogs/registry.xml"/> ++ <nextCatalog catalog="./../catalogs/./registry.xml"/> ++</catalog> ++ +diff --git a/testcatalog.c b/testcatalog.c +new file mode 100644 +index 0000000..86d33bd +--- /dev/null ++++ b/testcatalog.c +@@ -0,0 +1,96 @@ ++/* ++ * testcatalog.c: C program to run libxml2 catalog.c unit tests ++ * ++ * To compile on Unixes: ++ * cc -o testcatalog `xml2-config --cflags` testcatalog.c `xml2-config --libs` -lpthread ++ * ++ * See Copyright for the status of this software. ++ * ++ * Author: Daniel Garcia <[email protected]> ++ */ ++ ++ ++#include "libxml.h" ++#include <stdio.h> ++ ++#ifdef LIBXML_CATALOG_ENABLED ++#include <libxml/catalog.h> ++ ++/* Test catalog resolve uri with recursive catalog */ ++static int ++testRecursiveDelegateUri(void) { ++ int ret = 0; ++ const char *cat = "test/catalogs/catalog-recursive.xml"; ++ const char *entity = "/foo.ent"; ++ xmlChar *resolved = NULL; ++ ++ xmlInitParser(); ++ xmlLoadCatalog(cat); ++ ++ /* This should trigger recursive error */ ++ resolved = xmlCatalogResolveURI(BAD_CAST entity); ++ if (resolved != NULL) { ++ fprintf(stderr, "CATALOG-FAILURE: Catalog %s entity should fail to resolve\n", entity); ++ ret = 1; ++ } ++ xmlCatalogCleanup(); ++ ++ return ret; ++} ++ ++/* Test parsing repeated NextCatalog */ ++static int ++testRepeatedNextCatalog(void) { ++ int ret = 0; ++ int i = 0; ++ const char *cat = "test/catalogs/repeated-next-catalog.xml"; ++ const char *entity = "/foo.ent"; ++ xmlDocPtr doc = NULL; ++ xmlNodePtr node = NULL; ++ ++ xmlInitParser(); ++ ++ xmlLoadCatalog(cat); ++ /* To force the complete recursive load */ ++ xmlCatalogResolveURI(BAD_CAST entity); ++ /** ++ * Ensure that the doc doesn't contain the same nextCatalog ++ */ ++ doc = xmlCatalogDumpDoc(); ++ xmlCatalogCleanup(); ++ ++ if (doc == NULL) { ++ fprintf(stderr, "CATALOG-FAILURE: Failed to dump the catalog\n"); ++ return 1; ++ } ++ ++ /* Just the root "catalog" node with a series of nextCatalog */ ++ node = xmlDocGetRootElement(doc); ++ node = node->children; ++ for (i=0; node != NULL; node=node->next, i++) {} ++ if (i > 1) { ++ fprintf(stderr, "CATALOG-FAILURE: Found %d nextCatalog entries and should be 1\n", i); ++ ret = 1; ++ } ++ ++ xmlFreeDoc(doc); ++ ++ return ret; ++} ++ ++int ++main(void) { ++ int err = 0; ++ ++ err |= testRecursiveDelegateUri(); ++ err |= testRepeatedNextCatalog(); ++ ++ return err; ++} ++#else ++/* No catalog, so everything okay */ ++int ++main(void) { ++ return 0; ++} ++#endif diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,22 @@ +From: Jayakrishna Menon <[email protected]> +Date: Tue, 10 Feb 2026 14:24:15 -0700 +Subject: use duplicating variant in relaxng to mitigate UAF + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/df2ba65f661addfba50bdb7f280d594781249dfc +--- + relaxng.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/relaxng.c b/relaxng.c +index 3c6643e..42effaf 100644 +--- a/relaxng.c ++++ b/relaxng.c +@@ -8963,7 +8963,7 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt, + + if ((ret == 0) && (ctxt->state->value != NULL) && + (ctxt->state->value != ctxt->state->endvalue)) { +- VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA, ++ VALID_ERR2P(XML_RELAXNG_ERR_LISTEXTRA, + ctxt->state->value); + ret = -1; + } diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0038-fix-memory-leak-in-issue-1054.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0038-fix-memory-leak-in-issue-1054.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0038-fix-memory-leak-in-issue-1054.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0038-fix-memory-leak-in-issue-1054.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,44 @@ +From: Yun <[email protected]> +Date: Wed, 11 Feb 2026 22:32:12 +0000 +Subject: fix memory leak in issue 1054 + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/8d77ac83082288e6b11259266e0ce56095ecdd69 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/work_items/1054 +--- + xmlwriter.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/xmlwriter.c b/xmlwriter.c +index 49b3012..6d52aa2 100644 +--- a/xmlwriter.c ++++ b/xmlwriter.c +@@ -1872,6 +1872,7 @@ xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, + if (p == 0) { + xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, + "xmlTextWriterStartAttributeNS : out of memory!\n"); ++ xmlFree(buf); + return -1; + } + +@@ -1880,12 +1881,20 @@ xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, + if (p->uri == 0) { + xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, + "xmlTextWriterStartAttributeNS : out of memory!\n"); ++ xmlFree(p->prefix); + xmlFree(p); + return -1; + } + p->elem = xmlListFront(writer->nodes); + +- xmlListPushFront(writer->nsstack, p); ++ if (xmlListPushFront(writer->nsstack, p) == 0) { ++ xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, ++ "xmlTextWriterStartAttributeNS : out of memory!\n"); ++ xmlFree(p->uri); ++ xmlFree(p->prefix); ++ xmlFree(p); ++ return -1; ++ } + } + } + diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0039-schematron-fix-additional-memory-leaks-on-error-path.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0039-schematron-fix-additional-memory-leaks-on-error-path.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0039-schematron-fix-additional-memory-leaks-on-error-path.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0039-schematron-fix-additional-memory-leaks-on-error-path.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,51 @@ +From: ylwango613 <[email protected]> +Date: Tue, 24 Feb 2026 18:23:50 +0800 +Subject: schematron: fix additional memory leaks on error paths + +In xmlSchematronParseRule, free report when xmlSchematronAddTest fails +in the assert and report blocks. + +In xmlSchematronAddTest, free the compiled XPath expression when +xmlMalloc fails. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/99bf8af1bb9654dd6746c73456ce17412fe442f3 +--- + schematron.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/schematron.c b/schematron.c +index d90f367..944fc3c 100644 +--- a/schematron.c ++++ b/schematron.c +@@ -331,6 +331,7 @@ xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt, + ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest)); + if (ret == NULL) { + xmlSchematronPErrMemory(ctxt, "allocating schema test", node); ++ xmlXPathFreeCompExpr(comp); + return (NULL); + } + memset(ret, 0, sizeof(xmlSchematronTest)); +@@ -906,8 +907,10 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, + + testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT, + ruleptr, cur, test, report); +- if (testptr == NULL) ++ if (testptr == NULL) { + xmlFree(test); ++ xmlFree(report); ++ } + } + } else if (IS_SCHEMATRON(cur, "report")) { + nbChecks++; +@@ -929,8 +932,10 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, + + testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT, + ruleptr, cur, test, report); +- if (testptr == NULL) ++ if (testptr == NULL) { + xmlFree(test); ++ xmlFree(report); ++ } + } + } else { + xmlSchematronPErr(ctxt, cur, diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,45 @@ +From: ylwango613 <[email protected]> +Date: Tue, 24 Feb 2026 20:19:43 +0800 +Subject: catalog: fix stack overflow from self-referencing SGML CATALOG + entries + +An SGML catalog file with multiple CATALOG directives referencing itself +causes exponential recursion in xmlParseSGMLCatalog(), leading to stack +overflow. With K self-referencing entries and MAX_CATAL_DEPTH=50, total +recursive parses = K^50. + +Add deduplication by registering expanded filenames in the catalog hash +table before calling xmlExpandCatalog(), consistent with the existing +super branch. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/4982ee83f91ed598de793b280c8990646726c440 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/work_items/1064 +--- + catalog.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/catalog.c b/catalog.c +index df97a67..6559a89 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -2559,10 +2559,19 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, + } + } else { + xmlChar *filename; ++ xmlCatalogEntryPtr entry; + + filename = xmlBuildURI(sysid, base); + if (filename != NULL) { +- xmlExpandCatalog(catal, (const char *)filename, depth); ++ entry = xmlNewCatalogEntry(type, sysid, NULL, NULL, ++ XML_CATA_PREFER_NONE, NULL); ++ res = xmlHashAddEntry(catal->sgml, filename, entry); ++ if (res < 0) { ++ xmlFreeCatalogEntry(entry, NULL); ++ } else { ++ xmlExpandCatalog(catal, ++ (const char *)filename, depth); ++ } + xmlFree(filename); + } + } diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-49794_49796.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-49794_49796.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-49794_49796.patch 2025-10-11 14:55:59.000000000 +0200 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-49794_49796.patch 2026-06-07 19:02:23.000000000 +0200 @@ -26,19 +26,42 @@ create mode 100644 test/schematron/cve-2025-49796.sct create mode 100644 test/schematron/cve-2025-49796_0.xml +Index: libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49794_0 +=================================================================== +--- /dev/null ++++ libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49794_0 +@@ -0,0 +1,7 @@ ++<?xml version="1.0"?> ++<librar0> ++ <boo0 t=""> ++ <author/> ++ </boo0> ++ <ins/> ++</librar0> Index: libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49794_0.err =================================================================== --- /dev/null +++ libxml2-2.12.7+dfsg+really2.9.14/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: +@@ -0,0 +1,3 @@ ++Pattern: ++/librar0/boo0 line 2: +./test/schematron/cve-2025-49794_0.xml fails to validate +Index: libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49796_0 +=================================================================== +--- /dev/null ++++ libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49796_0 +@@ -0,0 +1,4 @@ ++<?xml version="1.0"?> ++<librar0> ++ <boo0/> ++</librar0> Index: libxml2-2.12.7+dfsg+really2.9.14/result/schematron/cve-2025-49796_0.err =================================================================== --- /dev/null +++ libxml2-2.12.7+dfsg+really2.9.14/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: +@@ -0,0 +1,3 @@ ++Pattern: ++/librar0/boo0 line 2: +./test/schematron/cve-2025-49796_0.xml fails to validate Index: libxml2-2.12.7+dfsg+really2.9.14/schematron.c =================================================================== diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-8732.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-8732.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-8732.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-8732.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,149 @@ +From: Nathan <[email protected]> +Date: Wed, 10 Sep 2025 18:11:50 +0300 +Subject: fix: Prevent infinite recursion in xmlCatalogListXMLResolve + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/3425dece47c8db600f8d7328ae2d7ddfaa0d7b2d +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/958 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-8732 +--- + catalog.c | 28 ++++++++++++++++++++-------- + result/catalogs/recursive | 1 + + test/catalogs/recursive.script | 0 + test/catalogs/recursive.sgml | 1 + + 4 files changed, 22 insertions(+), 8 deletions(-) + create mode 100644 result/catalogs/recursive + create mode 100644 test/catalogs/recursive.script + create mode 100644 test/catalogs/recursive.sgml + +diff --git a/catalog.c b/catalog.c +index e071b49..b25a630 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -92,7 +92,7 @@ unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long); + #endif + + static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID); +-static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename); ++static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename, int depth); + + /************************************************************************ + * * +@@ -2320,6 +2320,7 @@ xmlGetSGMLCatalogEntryType(const xmlChar *name) { + * @file: the filepath for the catalog + * @super: should this be handled as a Super Catalog in which case + * parsing is not recursive ++ * @depth: the current depth of the catalog + * + * Parse an SGML catalog content and fill up the @catal hash table with + * the new entries found. +@@ -2328,13 +2329,19 @@ xmlGetSGMLCatalogEntryType(const xmlChar *name) { + */ + static int + xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, +- const char *file, int super) { ++ const char *file, int super, int depth) { + const xmlChar *cur = value; + xmlChar *base = NULL; + int res; + + if ((cur == NULL) || (file == NULL)) + return(-1); ++ ++ /* Check recursion depth */ ++ if (depth > MAX_CATAL_DEPTH) { ++ return(-1); ++ } ++ + base = xmlStrdup((const xmlChar *) file); + + while ((cur != NULL) && (cur[0] != 0)) { +@@ -2512,7 +2519,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, + + filename = xmlBuildURI(sysid, base); + if (filename != NULL) { +- xmlExpandCatalog(catal, (const char *)filename); ++ xmlExpandCatalog(catal, (const char *)filename, depth); + xmlFree(filename); + } + } +@@ -2662,7 +2669,7 @@ xmlLoadSGMLSuperCatalog(const char *filename) + return(NULL); + } + +- ret = xmlParseSGMLCatalog(catal, content, filename, 1); ++ ret = xmlParseSGMLCatalog(catal, content, filename, 1, 0); + xmlFree(content); + if (ret < 0) { + xmlFreeCatalog(catal); +@@ -2708,7 +2715,7 @@ xmlLoadACatalog(const char *filename) + xmlFree(content); + return(NULL); + } +- ret = xmlParseSGMLCatalog(catal, content, filename, 0); ++ ret = xmlParseSGMLCatalog(catal, content, filename, 0, 0); + if (ret < 0) { + xmlFreeCatalog(catal); + xmlFree(content); +@@ -2731,6 +2738,7 @@ xmlLoadACatalog(const char *filename) + * xmlExpandCatalog: + * @catal: a catalog + * @filename: a file path ++ * @depth: the current depth of the catalog + * + * Load the catalog and expand the existing catal structure. + * This can be either an XML Catalog or an SGML Catalog +@@ -2738,13 +2746,17 @@ xmlLoadACatalog(const char *filename) + * Returns 0 in case of success, -1 in case of error + */ + static int +-xmlExpandCatalog(xmlCatalogPtr catal, const char *filename) ++xmlExpandCatalog(xmlCatalogPtr catal, const char *filename, int depth) + { + int ret; + + if ((catal == NULL) || (filename == NULL)) + return(-1); + ++ /* Check recursion depth */ ++ if (depth > MAX_CATAL_DEPTH) { ++ return(-1); ++ } + + if (catal->type == XML_SGML_CATALOG_TYPE) { + xmlChar *content; +@@ -2753,7 +2765,7 @@ xmlExpandCatalog(xmlCatalogPtr catal, const char *filename) + if (content == NULL) + return(-1); + +- ret = xmlParseSGMLCatalog(catal, content, filename, 0); ++ ret = xmlParseSGMLCatalog(catal, content, filename, 0, depth + 1); + if (ret < 0) { + xmlFree(content); + return(-1); +@@ -3221,7 +3233,7 @@ xmlLoadCatalog(const char *filename) + return(0); + } + +- ret = xmlExpandCatalog(xmlDefaultCatalog, filename); ++ ret = xmlExpandCatalog(xmlDefaultCatalog, filename, 0); + xmlRMutexUnlock(xmlCatalogMutex); + return(ret); + } +diff --git a/result/catalogs/recursive b/result/catalogs/recursive +new file mode 100644 +index 0000000..56ca91e +--- /dev/null ++++ b/result/catalogs/recursive +@@ -0,0 +1 @@ ++> +\ No newline at end of file +diff --git a/test/catalogs/recursive.script b/test/catalogs/recursive.script +new file mode 100644 +index 0000000..e69de29 +diff --git a/test/catalogs/recursive.sgml b/test/catalogs/recursive.sgml +new file mode 100644 +index 0000000..ac2148b +--- /dev/null ++++ b/test/catalogs/recursive.sgml +@@ -0,0 +1 @@ ++CATALOG recursive.sgml diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0989.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0989.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0989.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0989.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,308 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Fri, 10 Oct 2025 09:38:31 +0200 +Subject: Add RelaxNG include limit + +This patch adds a default xmlRelaxNGIncludeLimit of 1.000, and that +limit can be modified at runtime with the env variable +RNG_INCLUDE_LIMIT. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/66c52b3ac6c32ab112ec2a3bf41e6c30948be113 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/998 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374 +Bug-Debian-Security: https://deb.freexian.com/extended-lts/tracker/CVE-2026-0989 +Bug-Debian: https://bugs.debian.org/1125691 +--- + include/libxml/relaxng.h | 4 ++ + relaxng.c | 63 ++++++++++++++++++++++++++++-- + runtest.c | 67 ++++++++++++++++++++++++++++++++ + test/relaxng/include/include-limit.rng | 4 ++ + test/relaxng/include/include-limit_1.rng | 4 ++ + test/relaxng/include/include-limit_2.rng | 4 ++ + test/relaxng/include/include-limit_3.rng | 8 ++++ + 7 files changed, 150 insertions(+), 4 deletions(-) + create mode 100644 test/relaxng/include/include-limit.rng + create mode 100644 test/relaxng/include/include-limit_1.rng + create mode 100644 test/relaxng/include/include-limit_2.rng + create mode 100644 test/relaxng/include/include-limit_3.rng + +diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h +index f269c9e..d521679 100644 +--- a/include/libxml/relaxng.h ++++ b/include/libxml/relaxng.h +@@ -138,6 +138,10 @@ XMLPUBFUN int XMLCALL + + XMLPUBFUN void XMLCALL + xmlRelaxNGFreeParserCtxt (xmlRelaxNGParserCtxtPtr ctxt); ++XMLPUBFUN int XMLCALL ++ xmlRelaxParserSetIncLImit (xmlRelaxNGParserCtxtPtr ctxt, ++ int limit); ++ + XMLPUBFUN void XMLCALL + xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt, + xmlRelaxNGValidityErrorFunc err, +diff --git a/relaxng.c b/relaxng.c +index c4c26cb..3c6643e 100644 +--- a/relaxng.c ++++ b/relaxng.c +@@ -18,6 +18,8 @@ + + #ifdef LIBXML_SCHEMAS_ENABLED + ++#include <errno.h> ++#include <stdlib.h> + #include <string.h> + #include <stdio.h> + #include <stddef.h> +@@ -40,6 +42,12 @@ + static const xmlChar *xmlRelaxNGNs = (const xmlChar *) + "http://relaxng.org/ns/structure/1.0"; + ++/* ++ * Default include limit, this can be override with RNG_INCLUDE_LIMIT ++ * env variable ++ */ ++static const int _xmlRelaxNGIncludeLimit = 1000; ++ + #define IS_RELAXNG(node, typ) \ + ((node != NULL) && (node->ns != NULL) && \ + (node->type == XML_ELEMENT_NODE) && \ +@@ -245,6 +253,7 @@ struct _xmlRelaxNGParserCtxt { + int incNr; /* Depth of the include parsing stack */ + int incMax; /* Max depth of the parsing stack */ + xmlRelaxNGIncludePtr *incTab; /* array of incs */ ++ int incLimit; /* Include limit, to avoid stack-overflow on parse */ + + int idref; /* requires idref checking */ + +@@ -1430,6 +1439,23 @@ xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags) + return(0); + } + ++/** ++ * Semi private function used to set the include recursion limit to a ++ * parser context. Set to 0 to use the default value. ++ * ++ * @param ctxt a RelaxNG parser context ++ * @param limit the new include depth limit ++ * @returns 0 if success and -1 in case of error ++ */ ++int ++xmlRelaxParserSetIncLImit(xmlRelaxNGParserCtxtPtr ctxt, int limit) ++{ ++ if (ctxt == NULL) return(-1); ++ if (limit < 0) return(-1); ++ ctxt->incLimit = limit; ++ return(0); ++} ++ + /************************************************************************ + * * + * Document functions * +@@ -1445,7 +1471,7 @@ static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, + * + * Pushes a new include on top of the include stack + * +- * Returns 0 in case of error, the index in the stack otherwise ++ * Returns -1 in case of error, the index in the stack otherwise + */ + static int + xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt, +@@ -1459,9 +1485,15 @@ xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt, + sizeof(ctxt->incTab[0])); + if (ctxt->incTab == NULL) { + xmlRngPErrMemory(ctxt, "allocating include\n"); +- return (0); ++ return (-1); + } + } ++ if (ctxt->incNr >= ctxt->incLimit) { ++ xmlRngPErr(ctxt, (xmlNodePtr)value->doc, XML_RNGP_PARSE_ERROR, ++ "xmlRelaxNG: inclusion recursion limit reached\n", NULL, NULL); ++ return(-1); ++ } ++ + if (ctxt->incNr >= ctxt->incMax) { + ctxt->incMax *= 2; + ctxt->incTab = +@@ -1470,7 +1502,7 @@ xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt, + sizeof(ctxt->incTab[0])); + if (ctxt->incTab == NULL) { + xmlRngPErrMemory(ctxt, "allocating include\n"); +- return (0); ++ return (-1); + } + } + ctxt->incTab[ctxt->incNr] = value; +@@ -1664,7 +1696,9 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL, + /* + * push it on the stack + */ +- xmlRelaxNGIncludePush(ctxt, ret); ++ if (xmlRelaxNGIncludePush(ctxt, ret) < 0) { ++ return (NULL); ++ } + + /* + * Some preprocessing of the document content, this include recursing +@@ -7511,11 +7545,32 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt) + xmlDocPtr doc; + xmlNodePtr root; + ++ const char *include_limit_env = getenv("RNG_INCLUDE_LIMIT"); ++ + xmlRelaxNGInitTypes(); + + if (ctxt == NULL) + return (NULL); + ++ if (ctxt->incLimit == 0) { ++ ctxt->incLimit = _xmlRelaxNGIncludeLimit; ++ if (include_limit_env != NULL) { ++ char *strEnd; ++ unsigned long val = 0; ++ errno = 0; ++ val = strtoul(include_limit_env, &strEnd, 10); ++ if (errno != 0 || *strEnd != 0 || val > INT_MAX) { ++ xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR, ++ "xmlRelaxNGParse: invalid RNG_INCLUDE_LIMIT %s\n", ++ (const xmlChar*)include_limit_env, ++ NULL); ++ return(NULL); ++ } ++ if (val) ++ ctxt->incLimit = val; ++ } ++ } ++ + /* + * First step is to parse the input document into an DOM/Infoset + */ +diff --git a/runtest.c b/runtest.c +index e6b2cbb..4cd2e18 100644 +--- a/runtest.c ++++ b/runtest.c +@@ -3387,6 +3387,70 @@ rngTest(const char *filename, + return(ret); + } + ++/** ++ * Parse an RNG schemas with a custom RNG_INCLUDE_LIMIT ++ * ++ * @param filename the schemas file ++ * @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 ++rngIncludeTest(const char *filename, ++ const char *resul ATTRIBUTE_UNUSED, ++ const char *errr ATTRIBUTE_UNUSED, ++ int options ATTRIBUTE_UNUSED) { ++ xmlRelaxNGParserCtxtPtr ctxt; ++ xmlRelaxNGPtr schemas; ++ int ret = 0; ++ ++ /* first compile the schemas if possible */ ++ ctxt = xmlRelaxNGNewParserCtxt(filename); ++ xmlRelaxNGSetParserStructuredErrors(ctxt, testStructuredErrorHandler, ++ NULL); ++ ++ /* Should work */ ++ schemas = xmlRelaxNGParse(ctxt); ++ if (schemas == NULL) { ++ testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n", ++ filename); ++ ret = -1; ++ goto done; ++ } ++ xmlRelaxNGFree(schemas); ++ xmlRelaxNGFreeParserCtxt(ctxt); ++ ++ ctxt = xmlRelaxNGNewParserCtxt(filename); ++ /* Should fail */ ++ xmlRelaxParserSetIncLImit(ctxt, 2); ++ xmlRelaxNGSetParserStructuredErrors(ctxt, testStructuredErrorHandler, ++ NULL); ++ schemas = xmlRelaxNGParse(ctxt); ++ if (schemas != NULL) { ++ ret = -1; ++ xmlRelaxNGFree(schemas); ++ } ++ xmlRelaxNGFreeParserCtxt(ctxt); ++ ++ ctxt = xmlRelaxNGNewParserCtxt(filename); ++ /* Should work */ ++ xmlRelaxParserSetIncLImit(ctxt, 3); ++ xmlRelaxNGSetParserStructuredErrors(ctxt, testStructuredErrorHandler, ++ NULL); ++ schemas = xmlRelaxNGParse(ctxt); ++ if (schemas == NULL) { ++ testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n", ++ filename); ++ ret = -1; ++ goto done; ++ } ++ xmlRelaxNGFree(schemas); ++ ++done: ++ xmlRelaxNGFreeParserCtxt(ctxt); ++ return(ret); ++} ++ + #ifdef LIBXML_READER_ENABLED + /** + * rngStreamTest: +@@ -4459,6 +4523,9 @@ testDesc testDescriptions[] = { + { "Relax-NG regression tests" , + rngTest, "./test/relaxng/*.rng", NULL, NULL, NULL, + XML_PARSE_DTDATTR | XML_PARSE_NOENT }, ++ { "Relax-NG include limit tests" , ++ rngIncludeTest, "./test/relaxng/include/include-limit.rng", NULL, NULL, NULL, ++ 0 }, + #ifdef LIBXML_READER_ENABLED + { "Relax-NG streaming regression tests" , + rngStreamTest, "./test/relaxng/*.rng", NULL, NULL, NULL, +diff --git a/test/relaxng/include/include-limit.rng b/test/relaxng/include/include-limit.rng +new file mode 100644 +index 0000000..51f0394 +--- /dev/null ++++ b/test/relaxng/include/include-limit.rng +@@ -0,0 +1,4 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<grammar xmlns="http://relaxng.org/ns/structure/1.0"> ++ <include href="include-limit_1.rng"/> ++</grammar> +diff --git a/test/relaxng/include/include-limit_1.rng b/test/relaxng/include/include-limit_1.rng +new file mode 100644 +index 0000000..4672da3 +--- /dev/null ++++ b/test/relaxng/include/include-limit_1.rng +@@ -0,0 +1,4 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<grammar xmlns="http://relaxng.org/ns/structure/1.0"> ++ <include href="include-limit_2.rng"/> ++</grammar> +diff --git a/test/relaxng/include/include-limit_2.rng b/test/relaxng/include/include-limit_2.rng +new file mode 100644 +index 0000000..b35ecaa +--- /dev/null ++++ b/test/relaxng/include/include-limit_2.rng +@@ -0,0 +1,4 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<grammar xmlns="http://relaxng.org/ns/structure/1.0"> ++ <include href="include-limit_3.rng"/> ++</grammar> +diff --git a/test/relaxng/include/include-limit_3.rng b/test/relaxng/include/include-limit_3.rng +new file mode 100644 +index 0000000..86213c6 +--- /dev/null ++++ b/test/relaxng/include/include-limit_3.rng +@@ -0,0 +1,8 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<grammar xmlns="http://relaxng.org/ns/structure/1.0"> ++ <start> ++ <element name="root"> ++ <empty/> ++ </element> ++ </start> ++</grammar> diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0990.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0990.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0990.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0990.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,74 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Wed, 17 Dec 2025 15:24:08 +0100 +Subject: catalog: prevent inf recursion in xmlCatalogXMLResolveURI + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/ac6f0fde1476c41f59ad0c68ada3394599ebf2ae +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1018 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-0990 +Bug-Debian: https://bugs.debian.org/1125695 +--- + catalog.c | 31 +++++++++++++++++++++++-------- + 1 file changed, 23 insertions(+), 8 deletions(-) + +diff --git a/catalog.c b/catalog.c +index b25a630..5eb249e 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -2099,12 +2099,21 @@ static xmlChar * + xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) { + xmlChar *ret = NULL; + xmlChar *urnID = NULL; ++ xmlCatalogEntryPtr cur = NULL; + + if (catal == NULL) + return(NULL); + if (URI == NULL) + return(NULL); + ++ if (catal->depth > MAX_CATAL_DEPTH) { ++ xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION, ++ "Detected recursion in catalog %s\n", ++ catal->name, NULL, NULL); ++ return(NULL); ++ } ++ catal->depth++; ++ + if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) { + urnID = xmlCatalogUnWrapURN(URI); + if (xmlDebugCatalogs) { +@@ -2118,21 +2127,27 @@ xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) { + ret = xmlCatalogListXMLResolve(catal, urnID, NULL); + if (urnID != NULL) + xmlFree(urnID); ++ catal->depth--; + return(ret); + } +- while (catal != NULL) { +- if (catal->type == XML_CATA_CATALOG) { +- if (catal->children == NULL) { +- xmlFetchXMLCatalogFile(catal); ++ cur = catal; ++ while (cur != NULL) { ++ if (cur->type == XML_CATA_CATALOG) { ++ if (cur->children == NULL) { ++ xmlFetchXMLCatalogFile(cur); + } +- if (catal->children != NULL) { +- ret = xmlCatalogXMLResolveURI(catal->children, URI); +- if (ret != NULL) ++ if (cur->children != NULL) { ++ ret = xmlCatalogXMLResolveURI(cur->children, URI); ++ if (ret != NULL) { ++ catal->depth--; + return(ret); ++ } + } + } +- catal = catal->next; ++ cur = cur->next; + } ++ ++ catal->depth--; + return(ret); + } + diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/01-4af23b523.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/01-4af23b523.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/01-4af23b523.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/01-4af23b523.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,47 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Fri, 19 Dec 2025 11:02:18 +0100 +Subject: catalog: Ignore repeated nextCatalog entries + +This patch makes the catalog parsing to ignore repeated entries of +nextCatalog with the same value. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/4af23b523de5b72f27faf3e8e8a99dde5f7b82a2 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1019 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-0992 +Bug-Debian: https://bugs.debian.org/1125696 +--- + catalog.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/catalog.c b/catalog.c +index 5eb249e..d88ca5d 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -1279,9 +1279,27 @@ xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer, + BAD_CAST "delegateURI", BAD_CAST "uriStartString", + BAD_CAST "catalog", prefer, cgroup); + } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) { ++ xmlCatalogEntryPtr prev = parent->children; ++ + entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG, + BAD_CAST "nextCatalog", NULL, + BAD_CAST "catalog", prefer, cgroup); ++ /* Avoid duplication of nextCatalog */ ++ while (prev != NULL) { ++ if ((prev->type == XML_CATA_NEXT_CATALOG) && ++ (xmlStrEqual (prev->URL, entry->URL)) && ++ (xmlStrEqual (prev->value, entry->value)) && ++ (prev->prefer == entry->prefer) && ++ (prev->group == entry->group)) { ++ if (xmlDebugCatalogs) ++ fprintf(stderr, ++ "Ignoring repeated nextCatalog %s\n", entry->URL); ++ xmlFreeCatalogEntry(entry, NULL); ++ entry = NULL; ++ break; ++ } ++ prev = prev->next; ++ } + } + if (entry != NULL) { + if (parent != NULL) { diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/02-096402c94.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/02-096402c94.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/02-096402c94.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-0992/02-096402c94.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,31 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Sun, 18 Jan 2026 19:47:11 +0100 +Subject: catalog: Do not check value for duplication nextCatalog + +The value field stores the path as it appears in the catalog definition, +the URL is built using xmlBuildURI that changes the relative paths to +absolute. + +This change fixes the issue of using relative path to the same catalog +in the same file. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/096402c942e9d9a049f283eb4e6da431289900e1 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1040 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-0992 +Bug-Debian: https://bugs.debian.org/1125696 +--- + catalog.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/catalog.c b/catalog.c +index d88ca5d..c211812 100644 +--- a/catalog.c ++++ b/catalog.c +@@ -1288,7 +1288,6 @@ xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer, + while (prev != NULL) { + if ((prev->type == XML_CATA_NEXT_CATALOG) && + (xmlStrEqual (prev->URL, entry->URL)) && +- (xmlStrEqual (prev->value, entry->value)) && + (prev->prefer == entry->prefer) && + (prev->group == entry->group)) { + if (xmlDebugCatalogs) diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-1757.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-1757.patch --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-1757.patch 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2026-1757.patch 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,34 @@ +From: Daniel Garcia Moreno <[email protected]> +Date: Thu, 23 Oct 2025 07:41:19 +0200 +Subject: shell: free cmdline before continue + +This patch frees the cmdline when it's not empty but it doesn't contain +any actual character. + +If the cmdline is just whitespaces or \r and \n, the loop continues +without freeing the cmdline string, so it's a leak. + +Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/5446460ad3229579c91506317fb80ab333d44414 +Bug: https://gitlab.gnome.org/GNOME/libxml2/-/issues/1009 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-1757 +--- + debugXML.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/debugXML.c b/debugXML.c +index dfde58e..98e7de0 100644 +--- a/debugXML.c ++++ b/debugXML.c +@@ -2874,8 +2874,11 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, + command[i++] = *cur++; + } + command[i] = 0; +- if (i == 0) ++ if (i == 0) { ++ free(cmdline); ++ cmdline = NULL; + continue; ++ } + + /* + * Parse the argument diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/series libxml2-2.12.7+dfsg+really2.9.14/debian/patches/series --- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/series 2025-10-11 14:55:59.000000000 +0200 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/series 2026-06-07 19:02:23.000000000 +0200 @@ -26,3 +26,15 @@ CVE-2025-6170.patch CVE-2025-7425.patch CVE-2025-9714.patch +CVE-2026-1757.patch +0030-Fix-memory-leak-of-prefix-in-xmlTextWriterStartEleme.patch +CVE-2025-8732.patch +CVE-2026-0990.patch +CVE-2026-0992/01-4af23b523.patch +CVE-2026-0992/02-096402c94.patch +0035-testcatalog-Add-new-tests-for-catalog.c.patch +CVE-2026-0989.patch +0037-use-duplicating-variant-in-relaxng-to-mitigate-UAF.patch +0038-fix-memory-leak-in-issue-1054.patch +0039-schematron-fix-additional-memory-leaks-on-error-path.patch +0040-catalog-fix-stack-overflow-from-self-referencing-SGM.patch diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/salsa-ci.yml libxml2-2.12.7+dfsg+really2.9.14/debian/salsa-ci.yml --- libxml2-2.12.7+dfsg+really2.9.14/debian/salsa-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ libxml2-2.12.7+dfsg+really2.9.14/debian/salsa-ci.yml 2026-06-07 19:02:23.000000000 +0200 @@ -0,0 +1,8 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml + +variables: + RELEASE: 'trixie' + SALSA_CI_DISABLE_LINTIAN: 1 + SALSA_CI_DISABLE_REPROTEST: 1
signature.asc
Description: PGP signature

