Compare commits
1 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 1a028b25ee |
127
libxml2-CVE-2025-10911.patch
Normal file
127
libxml2-CVE-2025-10911.patch
Normal file
@@ -0,0 +1,127 @@
|
||||
From 0e50b31902cdb1eb242eb361c123e9e033b2af87 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Garcia Moreno <daniel.garcia@suse.com>
|
||||
Date: Wed, 8 Oct 2025 09:18:51 +0200
|
||||
Subject: [PATCH] Ignore next/prev of documents when traversing XPath
|
||||
|
||||
See https://gitlab.gnome.org/GNOME/libxml2/-/issues/996
|
||||
---
|
||||
xpath.c | 66 ++++++++++++++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 49 insertions(+), 17 deletions(-)
|
||||
|
||||
Index: libxml2-2.14.5/xpath.c
|
||||
===================================================================
|
||||
--- libxml2-2.14.5.orig/xpath.c
|
||||
+++ libxml2-2.14.5/xpath.c
|
||||
@@ -6814,12 +6814,18 @@ xmlNodePtr
|
||||
xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||
if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
|
||||
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||
- return(NULL);
|
||||
+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||
+ return(NULL);
|
||||
+
|
||||
if (cur == (xmlNodePtr) ctxt->context->doc)
|
||||
return(NULL);
|
||||
+
|
||||
if (cur == NULL)
|
||||
- return(ctxt->context->node->next);
|
||||
+ cur = ctxt->context->node;
|
||||
+
|
||||
+ if (cur->type == XML_DOCUMENT_NODE)
|
||||
+ return(NULL);
|
||||
+
|
||||
return(cur->next);
|
||||
}
|
||||
|
||||
@@ -6839,17 +6845,23 @@ xmlNodePtr
|
||||
xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||
if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
|
||||
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||
- return(NULL);
|
||||
+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||
+ return(NULL);
|
||||
+
|
||||
if (cur == (xmlNodePtr) ctxt->context->doc)
|
||||
return(NULL);
|
||||
- if (cur == NULL)
|
||||
- return(ctxt->context->node->prev);
|
||||
- if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
|
||||
- cur = cur->prev;
|
||||
- if (cur == NULL)
|
||||
- return(ctxt->context->node->prev);
|
||||
+
|
||||
+ if (cur == NULL) {
|
||||
+ cur = ctxt->context->node;
|
||||
+ } else if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
|
||||
+ cur = cur->prev;
|
||||
+ if (cur == NULL)
|
||||
+ cur = ctxt->context->node;
|
||||
}
|
||||
+
|
||||
+ if (cur->type == XML_DOCUMENT_NODE)
|
||||
+ return(NULL);
|
||||
+
|
||||
return(cur->prev);
|
||||
}
|
||||
|
||||
@@ -6886,14 +6898,27 @@ xmlXPathNextFollowing(xmlXPathParserCont
|
||||
cur = (xmlNodePtr) ns->next;
|
||||
}
|
||||
}
|
||||
- if (cur == NULL) return(NULL) ; /* ERROR */
|
||||
- if (cur->next != NULL) return(cur->next) ;
|
||||
+
|
||||
+ /* ERROR */
|
||||
+ if (cur == NULL)
|
||||
+ return(NULL);
|
||||
+
|
||||
+ if (cur->type == XML_DOCUMENT_NODE)
|
||||
+ return(NULL);
|
||||
+
|
||||
+ if (cur->next != NULL)
|
||||
+ return(cur->next);
|
||||
+
|
||||
do {
|
||||
cur = cur->parent;
|
||||
- if (cur == NULL) break;
|
||||
- if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
|
||||
- if (cur->next != NULL) return(cur->next);
|
||||
+ if (cur == NULL)
|
||||
+ break;
|
||||
+ if (cur == (xmlNodePtr) ctxt->context->doc)
|
||||
+ return(NULL);
|
||||
+ if (cur->next != NULL && cur->type != XML_DOCUMENT_NODE)
|
||||
+ return(cur->next);
|
||||
} while (cur != NULL);
|
||||
+
|
||||
return(cur);
|
||||
}
|
||||
|
||||
@@ -7011,10 +7036,13 @@ xmlXPathNextPrecedingInternal(xmlXPathPa
|
||||
}
|
||||
ctxt->ancestor = cur->parent;
|
||||
}
|
||||
- if (cur->type == XML_NAMESPACE_DECL)
|
||||
+
|
||||
+ if (cur->type == XML_NAMESPACE_DECL || cur->type == XML_DOCUMENT_NODE)
|
||||
return(NULL);
|
||||
+
|
||||
if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
|
||||
cur = cur->prev;
|
||||
+
|
||||
while (cur->prev == NULL) {
|
||||
cur = cur->parent;
|
||||
if (cur == NULL)
|
||||
@@ -7025,6 +7053,10 @@ xmlXPathNextPrecedingInternal(xmlXPathPa
|
||||
return (cur);
|
||||
ctxt->ancestor = cur->parent;
|
||||
}
|
||||
+
|
||||
+ if (cur->type == XML_DOCUMENT_NODE)
|
||||
+ return(NULL);
|
||||
+
|
||||
cur = cur->prev;
|
||||
while (cur->last != NULL)
|
||||
cur = cur->last;
|
||||
142
libxml2-CVE-2025-8732.patch
Normal file
142
libxml2-CVE-2025-8732.patch
Normal file
@@ -0,0 +1,142 @@
|
||||
From eae9291aa73907694dd3a4274d306e31217e746e Mon Sep 17 00:00:00 2001
|
||||
From: Nathan <nathan.shain@echohq.com>
|
||||
Date: Wed, 10 Sep 2025 18:11:50 +0300
|
||||
Subject: [PATCH] fix: Prevent infinite recursion in xmlCatalogListXMLResolve
|
||||
|
||||
---
|
||||
catalog.c | 29 +++++++++++++++++++++--------
|
||||
result/catalogs/recursive | 1 +
|
||||
test/catalogs/recursive.script | 0
|
||||
test/catalogs/recursive.sgml | 1 +
|
||||
4 files changed, 23 insertions(+), 8 deletions(-)
|
||||
create mode 100644 result/catalogs/recursive
|
||||
create mode 100644 test/catalogs/recursive.script
|
||||
create mode 100644 test/catalogs/recursive.sgml
|
||||
|
||||
Index: libxml2-2.13.8/catalog.c
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/catalog.c
|
||||
+++ libxml2-2.13.8/catalog.c
|
||||
@@ -60,7 +60,7 @@
|
||||
#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);
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
@@ -2279,6 +2279,7 @@ xmlGetSGMLCatalogEntryType(const xmlChar
|
||||
* @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.
|
||||
@@ -2287,13 +2288,19 @@ xmlGetSGMLCatalogEntryType(const xmlChar
|
||||
*/
|
||||
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)) {
|
||||
@@ -2471,7 +2478,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal,
|
||||
|
||||
filename = xmlBuildURI(sysid, base);
|
||||
if (filename != NULL) {
|
||||
- xmlExpandCatalog(catal, (const char *)filename);
|
||||
+ xmlExpandCatalog(catal, (const char *)filename, depth);
|
||||
xmlFree(filename);
|
||||
}
|
||||
}
|
||||
@@ -2621,7 +2628,7 @@ xmlLoadSGMLSuperCatalog(const char *file
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
- ret = xmlParseSGMLCatalog(catal, content, filename, 1);
|
||||
+ ret = xmlParseSGMLCatalog(catal, content, filename, 1, 0);
|
||||
xmlFree(content);
|
||||
if (ret < 0) {
|
||||
xmlFreeCatalog(catal);
|
||||
@@ -2667,7 +2674,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);
|
||||
@@ -2690,6 +2697,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
|
||||
@@ -2697,13 +2705,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;
|
||||
@@ -2712,7 +2724,7 @@ xmlExpandCatalog(xmlCatalogPtr catal, co
|
||||
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);
|
||||
@@ -3154,7 +3166,7 @@ xmlLoadCatalog(const char *filename)
|
||||
return(0);
|
||||
}
|
||||
|
||||
- ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
|
||||
+ ret = xmlExpandCatalog(xmlDefaultCatalog, filename, 0);
|
||||
xmlRMutexUnlock(xmlCatalogMutex);
|
||||
return(ret);
|
||||
}
|
||||
Index: libxml2-2.13.8/result/catalogs/recursive
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libxml2-2.13.8/result/catalogs/recursive
|
||||
@@ -0,0 +1 @@
|
||||
+>
|
||||
\ No newline at end of file
|
||||
Index: libxml2-2.13.8/test/catalogs/recursive.sgml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libxml2-2.13.8/test/catalogs/recursive.sgml
|
||||
@@ -0,0 +1 @@
|
||||
+CATALOG recursive.sgml
|
||||
99
libxml2-CVE-2026-0990.patch
Normal file
99
libxml2-CVE-2026-0990.patch
Normal file
@@ -0,0 +1,99 @@
|
||||
From 1961208e958ca22f80a0b4e4c9d71cfa050aa982 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Garcia Moreno <daniel.garcia@suse.com>
|
||||
Date: Wed, 17 Dec 2025 15:24:08 +0100
|
||||
Subject: [PATCH 1/2] catalog: prevent inf recursion in xmlCatalogXMLResolveURI
|
||||
|
||||
Fix https://gitlab.gnome.org/GNOME/libxml2/-/issues/1018
|
||||
---
|
||||
catalog.c | 31 +++++++++++++++++++++++--------
|
||||
1 file changed, 23 insertions(+), 8 deletions(-)
|
||||
|
||||
Index: libxml2-2.13.8/catalog.c
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/catalog.c
|
||||
+++ libxml2-2.13.8/catalog.c
|
||||
@@ -1240,9 +1240,26 @@ xmlParseXMLCatalogNode(xmlNodePtr cur, x
|
||||
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) {
|
||||
@@ -2060,12 +2077,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) {
|
||||
@@ -2079,21 +2105,27 @@ xmlCatalogListXMLResolveURI(xmlCatalogEn
|
||||
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);
|
||||
}
|
||||
|
||||
350
libxml2-CVE-2026-0992.patch
Normal file
350
libxml2-CVE-2026-0992.patch
Normal file
@@ -0,0 +1,350 @@
|
||||
From f8399e62a31095bf1ced01827c33f9b29494046f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Garcia Moreno <daniel.garcia@suse.com>
|
||||
Date: Fri, 19 Dec 2025 12:27:54 +0100
|
||||
Subject: [PATCH 1/2] 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
|
||||
---
|
||||
CMakeLists.txt | 2 +
|
||||
Makefile.am | 6 ++
|
||||
catalog.c | 63 +++++++++++-----
|
||||
include/libxml/catalog.h | 2 +
|
||||
meson.build | 1 +
|
||||
test/catalogs/catalog-recursive.xml | 3 +
|
||||
test/catalogs/repeated-next-catalog.xml | 10 +++
|
||||
testcatalog.c | 96 +++++++++++++++++++++++++
|
||||
8 files changed, 164 insertions(+), 19 deletions(-)
|
||||
create mode 100644 test/catalogs/catalog-recursive.xml
|
||||
create mode 100644 test/catalogs/repeated-next-catalog.xml
|
||||
create mode 100644 testcatalog.c
|
||||
|
||||
Index: libxml2-2.13.8/CMakeLists.txt
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/CMakeLists.txt
|
||||
+++ libxml2-2.13.8/CMakeLists.txt
|
||||
@@ -505,6 +505,7 @@ if(LIBXML2_WITH_TESTS)
|
||||
runxmlconf
|
||||
runsuite
|
||||
testapi
|
||||
+ testcatalog
|
||||
testchar
|
||||
testdict
|
||||
testModule
|
||||
@@ -531,6 +532,7 @@ if(LIBXML2_WITH_TESTS)
|
||||
if(NOT WIN32)
|
||||
add_test(NAME testapi COMMAND testapi)
|
||||
endif()
|
||||
+ add_test(NAME testcatalog COMMAND testcatalog)
|
||||
add_test(NAME testchar COMMAND testchar)
|
||||
add_test(NAME testdict COMMAND testdict)
|
||||
add_test(NAME testparser COMMAND testparser WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
Index: libxml2-2.13.8/Makefile.am
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/Makefile.am
|
||||
+++ libxml2-2.13.8/Makefile.am
|
||||
@@ -21,6 +21,7 @@ check_PROGRAMS = \
|
||||
testModule \
|
||||
testThreads \
|
||||
testapi \
|
||||
+ testcatalog \
|
||||
testchar \
|
||||
testdict \
|
||||
testlimits \
|
||||
@@ -129,6 +130,10 @@ testlimits_SOURCES=testlimits.c
|
||||
testlimits_DEPENDENCIES = $(DEPS)
|
||||
testlimits_LDADD= $(LDADDS)
|
||||
|
||||
+testcatalog_SOURCES=testcatalog.c
|
||||
+testcatalog_DEPENDENCIES = $(DEPS)
|
||||
+testcatalog_LDADD= $(LDADDS)
|
||||
+
|
||||
testchar_SOURCES=testchar.c
|
||||
testchar_DEPENDENCIES = $(DEPS)
|
||||
testchar_LDADD= $(LDADDS)
|
||||
@@ -187,6 +192,7 @@ check-local:
|
||||
$(CHECKER) ./runtest$(EXEEXT)
|
||||
$(CHECKER) ./testrecurse$(EXEEXT)
|
||||
$(CHECKER) ./testapi$(EXEEXT)
|
||||
+ $(CHECKER) ./testcatalog$(EXEEXT)
|
||||
$(CHECKER) ./testchar$(EXEEXT)
|
||||
$(CHECKER) ./testdict$(EXEEXT)
|
||||
$(CHECKER) ./testparser$(EXEEXT)
|
||||
Index: libxml2-2.13.8/catalog.c
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/catalog.c
|
||||
+++ libxml2-2.13.8/catalog.c
|
||||
@@ -627,43 +627,54 @@ static void xmlDumpXMLCatalogNode(xmlCat
|
||||
}
|
||||
}
|
||||
|
||||
-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
|
||||
*/
|
||||
@@ -1249,7 +1260,6 @@ xmlParseXMLCatalogNode(xmlNodePtr cur, x
|
||||
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)
|
||||
@@ -3375,6 +3385,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 */
|
||||
|
||||
/**
|
||||
Index: libxml2-2.13.8/include/libxml/catalog.h
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/include/libxml/catalog.h
|
||||
+++ libxml2-2.13.8/include/libxml/catalog.h
|
||||
@@ -119,6 +119,8 @@ XMLPUBFUN void
|
||||
#ifdef LIBXML_OUTPUT_ENABLED
|
||||
XMLPUBFUN void
|
||||
xmlCatalogDump (FILE *out);
|
||||
+XMLPUBFUN xmlDocPtr
|
||||
+ xmlCatalogDumpDoc (void);
|
||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||
XMLPUBFUN xmlChar *
|
||||
xmlCatalogResolve (const xmlChar *pubID,
|
||||
Index: libxml2-2.13.8/meson.build
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/meson.build
|
||||
+++ libxml2-2.13.8/meson.build
|
||||
@@ -728,6 +728,7 @@ checks = [
|
||||
# 'testModule',
|
||||
'testThreads',
|
||||
'testapi',
|
||||
+ 'testcatalog',
|
||||
'testchar',
|
||||
'testdict',
|
||||
'testlimits',
|
||||
Index: libxml2-2.13.8/test/catalogs/catalog-recursive.xml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libxml2-2.13.8/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>
|
||||
Index: libxml2-2.13.8/test/catalogs/repeated-next-catalog.xml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libxml2-2.13.8/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>
|
||||
+
|
||||
Index: libxml2-2.13.8/testcatalog.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libxml2-2.13.8/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 <dani@danigm.net>
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+#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
|
||||
Index: libxml2-2.13.8/configure.ac
|
||||
===================================================================
|
||||
--- libxml2-2.13.8.orig/configure.ac
|
||||
+++ libxml2-2.13.8/configure.ac
|
||||
@@ -40,7 +40,7 @@ AC_SUBST(LIBXML_VERSION_EXTRA)
|
||||
|
||||
VERSION=${LIBXML_VERSION}
|
||||
|
||||
-AM_INIT_AUTOMAKE([1.16.3 foreign no-dist-gzip dist-xz])
|
||||
+AM_INIT_AUTOMAKE([1.15.1 foreign no-dist-gzip dist-xz])
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
36
libxml2-CVE-2026-1757.patch
Normal file
36
libxml2-CVE-2026-1757.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 160c8a43ba37dfb07ebe6446fbad9d0973d9279d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Garcia Moreno <daniel.garcia@suse.com>
|
||||
Date: Thu, 23 Oct 2025 07:41:19 +0200
|
||||
Subject: [PATCH] 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.
|
||||
|
||||
Fix https://gitlab.gnome.org/GNOME/libxml2/-/issues/1009
|
||||
---
|
||||
shell.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/shell.c b/shell.c
|
||||
index 43024b089..67f61c307 100644
|
||||
--- a/debugXML.c
|
||||
+++ b/debugXML.c
|
||||
@@ -1138,8 +1138,11 @@ xmllintShell(xmlDoc *doc, const char *filename, FILE * output)
|
||||
command[i++] = *cur++;
|
||||
}
|
||||
command[i] = 0;
|
||||
- if (i == 0)
|
||||
+ if (i == 0) {
|
||||
+ free(cmdline);
|
||||
+ cmdline = NULL;
|
||||
continue;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Parse the argument
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -1,10 +1,37 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Feb 13 12:16:01 UTC 2026 - David Anes <david.anes@suse.com>
|
||||
|
||||
- CVE-2026-0990: call stack overflow leading to application crash
|
||||
due to infinite recursion in `xmlCatalogXMLResolveURI` (bsc#1256807, bsc#1256811)
|
||||
* Add patch libxml2-CVE-2026-0990.patch
|
||||
|
||||
- CVE-2026-0992: excessive resource consumption when processing XML
|
||||
catalogs due to exponential behavior when handling `<nextCatalog>` elements (bsc#1256808, bsc#1256809, bsc#1256812)
|
||||
* Add patch libxml2-CVE-2026-0992.patch
|
||||
|
||||
- CVE-2025-8732: infinite recursion in catalog parsing functions when processing malformed SGML catalog files (bsc#1247858, bsc#1247850)
|
||||
* Add patch libxml2-CVE-2025-8732.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 4 13:40:16 UTC 2026 - Petr Gajdos <pgajdos@suse.com>
|
||||
|
||||
- CVE-2026-1757: memory leak in the `xmllint` interactive shell (bsc#1257593, bsc#1257594, bsc#1257595)
|
||||
* Add patch libxml2-CVE-2026-1757.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 4 09:39:12 UTC 2026 - Petr Gajdos <pgajdos@suse.com>
|
||||
|
||||
- CVE-2025-10911: use-after-free with key data stored cross-RVT (bsc#1250553)
|
||||
* Add patch libxml2-CVE-2025-10911.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 22 13:13:34 UTC 2026 - Daniel Garcia <daniel.garcia@suse.com>
|
||||
|
||||
- Add patch libxml2-CVE-2026-0989.patch, to fix call stack exhaustion
|
||||
leading to application crash due to RelaxNG parser not limiting the
|
||||
recursion depth when resolving `<include>` directives
|
||||
CVE-2026-0989, bsc#1256805, https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374
|
||||
- CVE-2026-0989: call stack exhaustion leading to application crash
|
||||
due to RelaxNG parser not limiting the recursion depth when
|
||||
resolving `<include>` directives (bsc#1256804, bsc#1256805, bsc#1256810)
|
||||
* Add patch libxml2-CVE-2026-0989.patch
|
||||
* https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jul 18 11:12:01 UTC 2025 - pgajdos@suse.com
|
||||
|
||||
26
libxml2.spec
26
libxml2.spec
@@ -43,9 +43,28 @@ Patch0: libxml2-python3-unicode-errors.patch
|
||||
# PATCH-FIX-UPSTREAM libxml2-python3-string-null-check.patch bsc#1065270 mgorse@suse.com
|
||||
# https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/15
|
||||
Patch1: libxml2-python3-string-null-check.patch
|
||||
# PATCH-FIX-UPSTREAM libxml2-CVE-2026-0989.patch bsc#1256805 daniel.garcia@suse.com
|
||||
# https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374
|
||||
Patch2: libxml2-CVE-2026-0989.patch
|
||||
# CVE-2025-8732: infinite recursion in catalog parsing functions when processing malformed SGML catalog files (bsc#1247858, bsc#1247850)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/337
|
||||
Patch2: libxml2-CVE-2025-8732.patch
|
||||
# CVE-2026-0989: call stack exhaustion leading to application crash due to RelaxNG parser not limiting the recursion depth when resolving `<include>` directives (bsc#1256804, bsc#1256805, bsc#1256810)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374
|
||||
Patch3: libxml2-CVE-2026-0989.patch
|
||||
# CVE-2025-10911: use-after-free with key data stored cross-RVT (bsc#1250553)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/345
|
||||
Patch4: libxml2-CVE-2025-10911.patch
|
||||
# CVE-2026-1757: memory leak in the `xmllint` interactive shell (bsc#1257593, bsc#1257594, bsc#1257595)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/commit/160c8a43ba37dfb07ebe6446fbad9d0973d9279d
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/issues/1009
|
||||
Patch5: libxml2-CVE-2026-1757.patch
|
||||
# CVE-2026-0990: call stack overflow leading to application crash due to infinite recursion in `xmlCatalogXMLResolveURI` (bsc#1256806, bsc#1256807, bsc#1256811)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/368
|
||||
Patch6: libxml2-CVE-2026-0990.patch
|
||||
# CVE-2026-0992: excessive resource consumption when processing XML catalogs due to exponential behavior when handling `<nextCatalog>` elements (bsc#1256808, bsc#1256809, bsc#1256812)
|
||||
# - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/377
|
||||
Patch7: libxml2-CVE-2026-0992.patch
|
||||
# IMPORTANT NOTE: remove automake, libtool buildrequires (+ autoreconf in prep section) once CVE-2026-0992 patch is not needed anymore
|
||||
BuildRequires: automake
|
||||
BuildRequires: libtool
|
||||
|
||||
#
|
||||
### -- openSUSE patches range from 1000 to 1999 -- ###
|
||||
@@ -168,6 +187,7 @@ either at parse time or later once the document has been modified.
|
||||
|
||||
%prep
|
||||
%autosetup -p1 -n libxml2-%{version}
|
||||
autoreconf -ifv # Required by patch for CVE-2026-0992
|
||||
sed -i '1 s|/usr/bin/env python|/usr/bin/python3|' doc/apibuild.py
|
||||
|
||||
%build
|
||||
|
||||
Reference in New Issue
Block a user