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 - CVE-2026-1757: memory leak in the `xmllint` interactive shell (bsc#1257593, bsc#1257594, bsc#1257595) * Add patch libxml2-CVE-2026-1757.patch - CVE-2025-10911: use-after-free with key data stored cross-RVT (bsc#1250553) * Add patch libxml2-CVE-2025-10911.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) * Add patch libxml2-CVE-2026-0989.patch * https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/374 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libxml2?expand=0&rev=260
143 lines
4.6 KiB
Diff
143 lines
4.6 KiB
Diff
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.14.5/catalog.c
|
|
===================================================================
|
|
--- libxml2-2.14.5.orig/catalog.c
|
|
+++ libxml2-2.14.5/catalog.c
|
|
@@ -62,7 +62,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);
|
|
|
|
/************************************************************************
|
|
* *
|
|
@@ -2275,6 +2275,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.
|
|
@@ -2283,13 +2284,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)) {
|
|
@@ -2467,7 +2474,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal,
|
|
|
|
filename = xmlBuildURI(sysid, base);
|
|
if (filename != NULL) {
|
|
- xmlExpandCatalog(catal, (const char *)filename);
|
|
+ xmlExpandCatalog(catal, (const char *)filename, depth);
|
|
xmlFree(filename);
|
|
}
|
|
}
|
|
@@ -2617,7 +2624,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);
|
|
@@ -2663,7 +2670,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);
|
|
@@ -2686,6 +2693,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
|
|
@@ -2693,13 +2701,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;
|
|
@@ -2708,7 +2720,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);
|
|
@@ -3142,7 +3154,7 @@ xmlLoadCatalog(const char *filename)
|
|
return(0);
|
|
}
|
|
|
|
- ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
|
|
+ ret = xmlExpandCatalog(xmlDefaultCatalog, filename, 0);
|
|
xmlRMutexUnlock(&xmlCatalogMutex);
|
|
return(ret);
|
|
}
|
|
Index: libxml2-2.14.5/result/catalogs/recursive
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libxml2-2.14.5/result/catalogs/recursive
|
|
@@ -0,0 +1 @@
|
|
+>
|
|
\ No newline at end of file
|
|
Index: libxml2-2.14.5/test/catalogs/recursive.sgml
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libxml2-2.14.5/test/catalogs/recursive.sgml
|
|
@@ -0,0 +1 @@
|
|
+CATALOG recursive.sgml
|