[xml/sgml-pkgs] Bug#1117843: trixie-pu: package libxml2.9/2.12.7+dfsg+really2.9.14-2.1+deb13u2
Guilhem Moulin
guilhem at debian.org
Sat Oct 11 14:56:18 BST 2025
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: libxml2.9 at packages.debian.org, security at debian.org
Control: affects -1 + src:libxml2.9
User: release.debian.org at packages.debian.org
Usertags: pu
[ Reason ]
Fix <no-dsa> issue CVE-2025-9714 and improve existing mitigation for
CVE-2025-7425.
[ Impact ]
Users will remain vulnerable to CVE-2025-9714, and will regress when
upgrading (a fix was uploaded to Bullseye LTS).
[ Tests ]
1/ PoC (from libxslt) at https://gitlab.gnome.org/GNOME/libxslt/-/issues/140
and https://gitlab.gnome.org/GNOME/libxslt/-/issues/148 .
2/ Autopkgtests for reverse (build-)dependencies.
[ Risks ]
The upstream fix for CVE-2025-9714 trivially applies to
2.12.7+dfsg+really2.9.14-2.1+deb13u1.
Backporting the mitigation for CVE-2025-7425 from
https://gitlab.gnome.org/-/project/1762/uploads/302ecfda701895ebd0fa438a66d1a7a4/gnome-libxslt-bug-140-apple-fix.diff
was more involved. Improvements over the existing
d/p/CVE-2025-7425.patch were discussed offlist with Aron Xu; a version
containing the resulting patch was uploaded to Bullseye LTS.
[ Checklist ]
[*] *all* changes are documented in the d/changelog
[*] I reviewed all changes and I approve them
[*] attach debdiff against the package in stable
[*] the issue is verified as fixed in unstable
[ Changes ]
* Fix CVE-2025-9714: Denial of service vulnerability via uncontrolled
recursion in XPath evaluation.
* Amend d/p/CVE-2025-7425.patch to better reflect the original fix.
--
Guilhem.
-------------- next part --------------
diffstat for libxml2-2.12.7+dfsg+really2.9.14 libxml2-2.12.7+dfsg+really2.9.14
changelog | 9
patches/CVE-2025-7425.patch | 441 +++++++++++++++-----------------------------
patches/CVE-2025-9714.patch | 113 +++++++++++
patches/series | 1
4 files changed, 277 insertions(+), 287 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-08-25 13:38:04.000000000 +0200
+++ libxml2-2.12.7+dfsg+really2.9.14/debian/changelog 2025-10-11 14:55:59.000000000 +0200
@@ -1,3 +1,12 @@
+libxml2 (2.12.7+dfsg+really2.9.14-2.1+deb13u2) trixie; urgency=high
+
+ * Non-maintainer upload.
+ * Fix CVE-2025-9714: Denial of service vulnerability via uncontrolled
+ recursion in XPath evaluation.
+ * Amend d/p/CVE-2025-7425.patch to better reflect the original fix.
+
+ -- Guilhem Moulin <guilhem at debian.org> Sat, 11 Oct 2025 14:55:59 +0200
+
libxml2 (2.12.7+dfsg+really2.9.14-2.1+deb13u1) trixie-security; urgency=high
* CVE-2025-7425: heap-use-after-free in xmlFreeID caused by `atype`
diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-7425.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-7425.patch
--- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-7425.patch 2025-08-25 13:37:38.000000000 +0200
+++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-7425.patch 2025-10-11 14:55:59.000000000 +0200
@@ -59,35 +59,42 @@
(xmlSchemaValAtomicType):
- Adopt macros by renaming the struct fields, recompiling and fixing
compiler failures, then changing the struct field names back.
+
+Origin: https://gitlab.gnome.org/-/project/1762/uploads/302ecfda701895ebd0fa438a66d1a7a4/gnome-libxslt-bug-140-apple-fix.diff
+Bug: https://gitlab.gnome.org/GNOME/libxslt/-/issues/140
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=2379274
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-7425
+Bug-Debian: https://bugs.debian.org/1109122
---
- HTMLparser.c | 1 +
- SAX2.c | 6 ++--
- include/libxml/tree.h | 14 ++++++++-
- parser.c | 8 ++---
- runxmlconf.c | 4 +--
- tree.c | 20 ++++++-------
- valid.c | 68 +++++++++++++++++++++----------------------
- xmlreader.c | 30 +++++++++----------
- xmlschemas.c | 4 +--
- xmlschemastypes.c | 12 ++++----
- 10 files changed, 90 insertions(+), 77 deletions(-)
+ HTMLparser.c | 2 +-
+ SAX2.c | 6 +++---
+ include/libxml/tree.h | 14 +++++++++++++-
+ parser.c | 26 +++++++++++++-------------
+ runxmlconf.c | 4 ++--
+ tree.c | 20 ++++++++++----------
+ valid.c | 16 ++++++++--------
+ xmlreader.c | 30 +++++++++++++++---------------
+ xmlschemas.c | 4 ++--
+ xmlschemastypes.c | 12 ++++++------
+ 10 files changed, 73 insertions(+), 61 deletions(-)
-Index: libxml2-2.9.14+dfsg/HTMLparser.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/HTMLparser.c
-+++ libxml2-2.9.14+dfsg/HTMLparser.c
-@@ -2514,6 +2514,7 @@ htmlNewDocNoDtD(const xmlChar *URI, cons
+diff --git a/HTMLparser.c b/HTMLparser.c
+index 4a56fb1..eabca3a 100644
+--- a/HTMLparser.c
++++ b/HTMLparser.c
+@@ -2514,7 +2514,7 @@ htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
cur->refs = NULL;
cur->_private = NULL;
cur->charset = XML_CHAR_ENCODING_UTF8;
+- cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
+ XML_DOC_SET_PROPERTIES(cur, XML_DOC_HTML | XML_DOC_USERBUILT);
- cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
if ((ExternalID != NULL) ||
(URI != NULL))
-Index: libxml2-2.9.14+dfsg/SAX2.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/SAX2.c
-+++ libxml2-2.9.14+dfsg/SAX2.c
+ xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
+diff --git a/SAX2.c b/SAX2.c
+index f7c77c2..0d8e84a 100644
+--- a/SAX2.c
++++ b/SAX2.c
@@ -970,7 +970,7 @@ xmlSAX2StartDocument(void *ctx)
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
return;
@@ -109,10 +116,10 @@
doc->parseFlags = ctxt->options;
if (ctxt->encoding != NULL)
doc->encoding = xmlStrdup(ctxt->encoding);
-Index: libxml2-2.9.14+dfsg/include/libxml/tree.h
-===================================================================
---- libxml2-2.9.14+dfsg.orig/include/libxml/tree.h
-+++ libxml2-2.9.14+dfsg/include/libxml/tree.h
+diff --git a/include/libxml/tree.h b/include/libxml/tree.h
+index 1e79be9..61178b2 100644
+--- a/include/libxml/tree.h
++++ b/include/libxml/tree.h
@@ -365,7 +365,6 @@ struct _xmlElement {
#endif
};
@@ -155,11 +162,11 @@
typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt;
typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr;
-Index: libxml2-2.9.14+dfsg/parser.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/parser.c
-+++ libxml2-2.9.14+dfsg/parser.c
-@@ -5523,7 +5523,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt
+diff --git a/parser.c b/parser.c
+index 603c0b3..f859296 100644
+--- a/parser.c
++++ b/parser.c
+@@ -5523,7 +5523,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
xmlErrMemory(ctxt, "New Doc failed");
return;
}
@@ -168,7 +175,7 @@
}
if (ctxt->myDoc->intSubset == NULL)
ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
-@@ -5594,7 +5594,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt
+@@ -5594,7 +5594,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
xmlErrMemory(ctxt, "New Doc failed");
return;
}
@@ -177,7 +184,7 @@
}
if (ctxt->myDoc->intSubset == NULL)
-@@ -7035,7 +7035,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr
+@@ -7035,7 +7035,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
xmlErrMemory(ctxt, "New Doc failed");
return;
}
@@ -186,7 +193,7 @@
}
if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
-@@ -7419,7 +7419,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt)
+@@ -7419,7 +7419,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
(nw != NULL) &&
(nw->type == XML_ELEMENT_NODE) &&
(nw->children == NULL))
@@ -195,11 +202,74 @@
break;
}
-Index: libxml2-2.9.14+dfsg/runxmlconf.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/runxmlconf.c
-+++ libxml2-2.9.14+dfsg/runxmlconf.c
-@@ -197,7 +197,7 @@ xmlconfTestInvalid(const char *id, const
+@@ -10858,13 +10858,13 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
+ }
+
+ if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
+- ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
++ XML_DOC_ADD_PROPERTIES(ctxt->myDoc, XML_DOC_WELLFORMED);
+ if (ctxt->valid)
+- ctxt->myDoc->properties |= XML_DOC_DTDVALID;
++ XML_DOC_ADD_PROPERTIES(ctxt->myDoc, XML_DOC_DTDVALID);
+ if (ctxt->nsWellFormed)
+- ctxt->myDoc->properties |= XML_DOC_NSVALID;
++ XML_DOC_ADD_PROPERTIES(ctxt->myDoc, XML_DOC_NSVALID);
+ if (ctxt->options & XML_PARSE_OLD10)
+- ctxt->myDoc->properties |= XML_DOC_OLD10;
++ XML_DOC_ADD_PROPERTIES(ctxt->myDoc, XML_DOC_OLD10);
+ }
+ if (! ctxt->wellFormed) {
+ ctxt->valid = 0;
+@@ -12748,7 +12748,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
+ xmlErrMemory(ctxt, "New Doc failed");
+ return(NULL);
+ }
+- ctxt->myDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
+ ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
+ BAD_CAST "none", BAD_CAST "none");
+
+@@ -12897,7 +12897,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
+- ctxt->myDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
+ ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
+ ExternalID, SystemID);
+ xmlParseExternalSubset(ctxt, ExternalID, SystemID);
+@@ -13047,7 +13047,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
+ xmlFreeParserCtxt(ctxt);
+ return(XML_ERR_INTERNAL_ERROR);
+ }
+- newDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(newDoc, XML_DOC_INTERNAL);
+ if (doc) {
+ newDoc->intSubset = doc->intSubset;
+ newDoc->extSubset = doc->extSubset;
+@@ -13366,7 +13366,7 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
+ xmlFreeParserCtxt(ctxt);
+ return(XML_ERR_INTERNAL_ERROR);
+ }
+- newDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(newDoc, XML_DOC_INTERNAL);
+ newDoc->dict = ctxt->dict;
+ xmlDictReference(newDoc->dict);
+ ctxt->myDoc = newDoc;
+@@ -13768,7 +13768,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
+ xmlFreeParserCtxt(ctxt);
+ return(-1);
+ }
+- newDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(newDoc, XML_DOC_INTERNAL);
+ if ((doc != NULL) && (doc->dict != NULL)) {
+ xmlDictFree(ctxt->dict);
+ ctxt->dict = doc->dict;
+diff --git a/runxmlconf.c b/runxmlconf.c
+index 8a37aa8..601a0af 100644
+--- a/runxmlconf.c
++++ b/runxmlconf.c
+@@ -197,7 +197,7 @@ xmlconfTestInvalid(const char *id, const char *filename, int options) {
id, filename);
} else {
/* invalidity should be reported both in the context and in the document */
@@ -208,7 +278,7 @@
test_log("test %s : %s failed to detect invalid document\n",
id, filename);
nb_errors++;
-@@ -229,7 +229,7 @@ xmlconfTestValid(const char *id, const c
+@@ -229,7 +229,7 @@ xmlconfTestValid(const char *id, const char *filename, int options) {
ret = 0;
} else {
/* validity should be reported both in the context and in the document */
@@ -217,10 +287,10 @@
test_log("test %s : %s failed to validate a valid document\n",
id, filename);
nb_errors++;
-Index: libxml2-2.9.14+dfsg/tree.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/tree.c
-+++ libxml2-2.9.14+dfsg/tree.c
+diff --git a/tree.c b/tree.c
+index 475c98f..3c64882 100644
+--- a/tree.c
++++ b/tree.c
@@ -1192,7 +1192,7 @@ xmlNewDoc(const xmlChar *version) {
cur->compression = -1; /* not initialized */
cur->doc = cur;
@@ -239,7 +309,7 @@
xmlRemoveID(cur->doc, cur);
}
if (cur->children != NULL) xmlFreeNodeList(cur->children);
-@@ -2838,7 +2838,7 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr
+@@ -2838,7 +2838,7 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
if(tree->type == XML_ELEMENT_NODE) {
prop = tree->properties;
while (prop != NULL) {
@@ -248,7 +318,7 @@
xmlRemoveID(tree->doc, prop);
}
-@@ -6952,9 +6952,9 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr n
+@@ -6952,9 +6952,9 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
/*
* Modify the attribute's value.
*/
@@ -260,7 +330,7 @@
}
if (prop->children != NULL)
xmlFreeNodeList(prop->children);
-@@ -6974,7 +6974,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr n
+@@ -6974,7 +6974,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
tmp = tmp->next;
}
}
@@ -292,7 +362,7 @@
((xmlAttrPtr) cur)->psvi = NULL;
}
break;
-@@ -9991,7 +9991,7 @@ xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ct
+@@ -9991,7 +9991,7 @@ xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
}
XML_TREE_ADOPT_STR(attr->name);
@@ -301,20 +371,11 @@
attr->psvi = NULL;
/*
* Walk content.
-Index: libxml2-2.9.14+dfsg/valid.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/valid.c
-+++ libxml2-2.9.14+dfsg/valid.c
-@@ -1906,7 +1906,7 @@ xmlScanIDAttributeDecl(xmlValidCtxtPtr c
- if (elem == NULL) return(0);
- cur = elem->attributes;
- while (cur != NULL) {
-- if (cur->atype == XML_ATTRIBUTE_ID) {
-+ if (XML_ATTR_GET_ATYPE(cur) == XML_ATTRIBUTE_ID) {
- ret ++;
- if ((ret > 1) && (err))
- xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_MULTIPLE_ID,
-@@ -2279,7 +2279,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, x
+diff --git a/valid.c b/valid.c
+index 36a0435..28822a2 100644
+--- a/valid.c
++++ b/valid.c
+@@ -2279,7 +2279,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
xmlBufferWriteChar(buf, ":");
}
xmlBufferWriteCHAR(buf, attr->name);
@@ -323,7 +384,7 @@
case XML_ATTRIBUTE_CDATA:
xmlBufferWriteChar(buf, " CDATA");
break;
-@@ -2758,7 +2758,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr
+@@ -2758,7 +2758,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
return(NULL);
}
if (attr != NULL)
@@ -332,16 +393,7 @@
return(ret);
}
-@@ -2837,7 +2837,7 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem,
- if ((fullelemname != felem) && (fullelemname != elem->name))
- xmlFree(fullelemname);
-
-- if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
-+ if ((attrDecl != NULL) && (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ID))
- return(1);
- }
- return(0);
-@@ -2878,7 +2878,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr at
+@@ -2878,7 +2878,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
xmlHashRemoveEntry(table, ID, xmlFreeIDTableEntry);
xmlFree(ID);
@@ -350,18 +402,7 @@
return(0);
}
-@@ -3157,8 +3157,8 @@ xmlIsRef(xmlDocPtr doc, xmlNodePtr elem,
- elem->name, attr->name);
-
- if ((attrDecl != NULL) &&
-- (attrDecl->atype == XML_ATTRIBUTE_IDREF ||
-- attrDecl->atype == XML_ATTRIBUTE_IDREFS))
-+ (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREF ||
-+ XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREFS))
- return(1);
- }
- return(0);
-@@ -3532,7 +3532,7 @@ xmlIsMixedElement(xmlDocPtr doc, const x
+@@ -3532,7 +3532,7 @@ xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
static int
xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
@@ -370,7 +411,7 @@
/*
* Use the new checks of production [4] [4a] amd [5] of the
* Update 5 of XML-1.0
-@@ -3562,7 +3562,7 @@ xmlIsDocNameStartChar(xmlDocPtr doc, int
+@@ -3562,7 +3562,7 @@ xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
static int
xmlIsDocNameChar(xmlDocPtr doc, int c) {
@@ -379,155 +420,16 @@
/*
* Use the new checks of production [4] [4a] amd [5] of the
* Update 5 of XML-1.0
-@@ -4112,7 +4112,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlV
-
- if (attrDecl == NULL)
- return(NULL);
-- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_CDATA)
- return(NULL);
-
- ret = xmlStrdup(value);
-@@ -4174,7 +4174,7 @@ xmlValidNormalizeAttributeValue(xmlDocPt
-
- if (attrDecl == NULL)
- return(NULL);
-- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_CDATA)
- return(NULL);
-
- ret = xmlStrdup(value);
-@@ -4189,7 +4189,7 @@ xmlValidateAttributeIdCallback(void *pay
- const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlAttributePtr attr = (xmlAttributePtr) payload;
- int *count = (int *) data;
-- if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
-+ if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID) (*count)++;
- }
-
- /**
-@@ -4221,7 +4221,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr
- /* Attribute Default Legal */
- /* Enumeration */
- if (attr->defaultValue != NULL) {
-- val = xmlValidateAttributeValueInternal(doc, attr->atype,
-+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attr),
- attr->defaultValue);
- if (val == 0) {
- xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT,
-@@ -4232,7 +4232,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr
- }
-
- /* ID Attribute Default */
-- if ((attr->atype == XML_ATTRIBUTE_ID)&&
-+ if ((XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID)&&
- (attr->def != XML_ATTRIBUTE_IMPLIED) &&
- (attr->def != XML_ATTRIBUTE_REQUIRED)) {
- xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ID_FIXED,
-@@ -4242,7 +4242,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr
- }
-
- /* One ID per Element Type */
-- if (attr->atype == XML_ATTRIBUTE_ID) {
-+ if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID) {
- int nbId;
-
- /* the trick is that we parse DtD as their own internal subset */
-@@ -4501,9 +4501,9 @@ xmlValidateOneAttribute(xmlValidCtxtPtr
+@@ -4501,7 +4501,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
attr->name, elem->name, NULL);
return(0);
}
- attr->atype = attrDecl->atype;
+ XML_ATTR_SET_ATYPE(attr, attrDecl->atype);
-- val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
-+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attrDecl), value);
+ val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
if (val == 0) {
- xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
- "Syntax of value for attribute %s of %s is not valid\n",
-@@ -4522,19 +4522,19 @@ xmlValidateOneAttribute(xmlValidCtxtPtr
- }
-
- /* Validity Constraint: ID uniqueness */
-- if (attrDecl->atype == XML_ATTRIBUTE_ID) {
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ID) {
- if (xmlAddID(ctxt, doc, value, attr) == NULL)
- ret = 0;
- }
-
-- if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
-- (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
-+ if ((XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREF) ||
-+ (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREFS)) {
- if (xmlAddRef(ctxt, doc, value, attr) == NULL)
- ret = 0;
- }
-
- /* Validity Constraint: Notation Attributes */
-- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_NOTATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- xmlNotationPtr nota;
-
-@@ -4564,7 +4564,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr
- }
-
- /* Validity Constraint: Enumeration */
-- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ENUMERATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
-@@ -4589,7 +4589,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr
-
- /* Extra check for the attribute value */
- ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
-- attrDecl->atype, value);
-+ XML_ATTR_GET_ATYPE(attrDecl), value);
-
- return(ret);
- }
-@@ -4688,7 +4688,7 @@ xmlNodePtr elem, const xmlChar *prefix,
- return(0);
- }
-
-- val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
-+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attrDecl), value);
- if (val == 0) {
- if (ns->prefix != NULL) {
- xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT,
-@@ -4738,7 +4738,7 @@ xmlNodePtr elem, const xmlChar *prefix,
- #endif
-
- /* Validity Constraint: Notation Attributes */
-- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_NOTATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- xmlNotationPtr nota;
-
-@@ -4780,7 +4780,7 @@ xmlNodePtr elem, const xmlChar *prefix,
- }
-
- /* Validity Constraint: Enumeration */
-- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
-+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ENUMERATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
-@@ -4818,10 +4818,10 @@ xmlNodePtr elem, const xmlChar *prefix,
- /* Extra check for the attribute value */
- if (ns->prefix != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc, ns->prefix,
-- attrDecl->atype, value);
-+ XML_ATTR_GET_ATYPE(attrDecl), value);
- } else {
- ret &= xmlValidateAttributeValue2(ctxt, doc, BAD_CAST "xmlns",
-- attrDecl->atype, value);
-+ XML_ATTR_GET_ATYPE(attrDecl), value);
- }
-
- return(ret);
-@@ -6574,7 +6574,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCt
+@@ -6574,7 +6574,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
while (IS_BLANK_CH(*cur)) cur++;
}
xmlFree(dup);
@@ -536,7 +438,7 @@
id = xmlGetID(ctxt->doc, name);
if (id == NULL) {
xmlErrValidNode(ctxt, attr->parent, XML_DTD_UNKNOWN_ID,
-@@ -6582,7 +6582,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCt
+@@ -6582,7 +6582,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
attr->name, name, NULL);
ctxt->valid = 0;
}
@@ -545,46 +447,11 @@
xmlChar *dup, *str = NULL, *cur, save;
dup = xmlStrdup(name);
-@@ -6782,7 +6782,7 @@ xmlValidateAttributeCallback(void *paylo
-
- if (cur == NULL)
- return;
-- switch (cur->atype) {
-+ switch (XML_ATTR_GET_ATYPE(cur)) {
- case XML_ATTRIBUTE_CDATA:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_IDREF :
-@@ -6797,7 +6797,7 @@ xmlValidateAttributeCallback(void *paylo
- if (cur->defaultValue != NULL) {
-
- ret = xmlValidateAttributeValue2(ctxt, ctxt->doc, cur->name,
-- cur->atype, cur->defaultValue);
-+ XML_ATTR_GET_ATYPE(cur), cur->defaultValue);
- if ((ret == 0) && (ctxt->valid == 1))
- ctxt->valid = 0;
- }
-@@ -6805,14 +6805,14 @@ xmlValidateAttributeCallback(void *paylo
- xmlEnumerationPtr tree = cur->tree;
- while (tree != NULL) {
- ret = xmlValidateAttributeValue2(ctxt, ctxt->doc,
-- cur->name, cur->atype, tree->name);
-+ cur->name, XML_ATTR_GET_ATYPE(cur), tree->name);
- if ((ret == 0) && (ctxt->valid == 1))
- ctxt->valid = 0;
- tree = tree->next;
- }
- }
- }
-- if (cur->atype == XML_ATTRIBUTE_NOTATION) {
-+ if (XML_ATTR_GET_ATYPE(cur) == XML_ATTRIBUTE_NOTATION) {
- doc = cur->doc;
- if (cur->elem == NULL) {
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
-Index: libxml2-2.9.14+dfsg/xmlreader.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/xmlreader.c
-+++ libxml2-2.9.14+dfsg/xmlreader.c
-@@ -753,7 +753,7 @@ xmlTextReaderStartElement(void *ctx, con
+diff --git a/xmlreader.c b/xmlreader.c
+index 67ff2cd..2a1a66a 100644
+--- a/xmlreader.c
++++ b/xmlreader.c
+@@ -753,7 +753,7 @@ xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
(ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
(ctxt->input->cur[1] == '>'))
@@ -674,7 +541,7 @@
xmlNodePtr tmp = reader->node->last;
xmlUnlinkNode(tmp);
xmlTextReaderFreeNode(reader, tmp);
-@@ -1741,7 +1741,7 @@ xmlTextReaderNext(xmlTextReaderPtr reade
+@@ -1741,7 +1741,7 @@ xmlTextReaderNext(xmlTextReaderPtr reader) {
return(xmlTextReaderRead(reader));
if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
return(xmlTextReaderRead(reader));
@@ -683,7 +550,7 @@
return(xmlTextReaderRead(reader));
do {
ret = xmlTextReaderRead(reader);
-@@ -3167,7 +3167,7 @@ xmlTextReaderIsEmptyElement(xmlTextReade
+@@ -3167,7 +3167,7 @@ xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
if (reader->in_xinclude > 0)
return(1);
#endif
@@ -692,7 +559,7 @@
}
/**
-@@ -4035,15 +4035,15 @@ xmlTextReaderPreserve(xmlTextReaderPtr r
+@@ -4035,15 +4035,15 @@ xmlTextReaderPreserve(xmlTextReaderPtr reader) {
return(NULL);
if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
@@ -711,11 +578,11 @@
parent = parent->parent;
}
return(cur);
-Index: libxml2-2.9.14+dfsg/xmlschemas.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/xmlschemas.c
-+++ libxml2-2.9.14+dfsg/xmlschemas.c
-@@ -6024,7 +6024,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserC
+diff --git a/xmlschemas.c b/xmlschemas.c
+index f309572..1ae078b 100644
+--- a/xmlschemas.c
++++ b/xmlschemas.c
+@@ -6024,7 +6024,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
/*
* NOTE: the IDness might have already be declared in the DTD
*/
@@ -724,7 +591,7 @@
xmlIDPtr res;
xmlChar *strip;
-@@ -6047,7 +6047,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserC
+@@ -6047,7 +6047,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
NULL, NULL, "Duplicate value '%s' of simple "
"type 'xs:ID'", value, NULL);
} else
@@ -733,11 +600,11 @@
}
} else if (ret > 0) {
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
-Index: libxml2-2.9.14+dfsg/xmlschemastypes.c
-===================================================================
---- libxml2-2.9.14+dfsg.orig/xmlschemastypes.c
-+++ libxml2-2.9.14+dfsg/xmlschemastypes.c
-@@ -2867,7 +2867,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+diff --git a/xmlschemastypes.c b/xmlschemastypes.c
+index af31be5..d40da49 100644
+--- a/xmlschemastypes.c
++++ b/xmlschemastypes.c
+@@ -2867,7 +2867,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
/*
* NOTE: the IDness might have already be declared in the DTD
*/
@@ -746,7 +613,7 @@
xmlIDPtr res;
xmlChar *strip;
-@@ -2880,7 +2880,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+@@ -2880,7 +2880,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
if (res == NULL) {
ret = 2;
} else {
@@ -755,7 +622,7 @@
}
}
}
-@@ -2905,7 +2905,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+@@ -2905,7 +2905,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
xmlFree(strip);
} else
xmlAddRef(NULL, node->doc, value, attr);
@@ -764,7 +631,7 @@
}
goto done;
case XML_SCHEMAS_IDREFS:
-@@ -2919,7 +2919,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+@@ -2919,7 +2919,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
@@ -773,7 +640,7 @@
}
goto done;
case XML_SCHEMAS_ENTITY:{
-@@ -2950,7 +2950,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+@@ -2950,7 +2950,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
@@ -782,7 +649,7 @@
}
goto done;
}
-@@ -2967,7 +2967,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr
+@@ -2967,7 +2967,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
diff -Nru libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-9714.patch libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-9714.patch
--- libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-9714.patch 1970-01-01 01:00:00.000000000 +0100
+++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/CVE-2025-9714.patch 2025-10-11 14:55:59.000000000 +0200
@@ -0,0 +1,113 @@
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Thu, 28 Jul 2022 20:21:24 +0200
+Subject: Make XPath depth check work with recursive invocations
+
+EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval
+recursively. Don't set depth to zero but keep and restore the original
+value to avoid stack overflows when abusing these functions.
+
+Origin: https://gitlab.gnome.org/GNOME/libxml2/-/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=2392605
+Bug: https://gitlab.gnome.org/GNOME/libxslt/-/issues/148
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-9714
+---
+ xpath.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/xpath.c b/xpath.c
+index c2d8458..028471d 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -13883,12 +13883,11 @@ static int
+ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
+ {
+ xmlXPathCompExprPtr comp;
++ int oldDepth;
+
+ if ((ctxt == NULL) || (ctxt->comp == NULL))
+ return(-1);
+
+- ctxt->context->depth = 0;
+-
+ if (ctxt->valueTab == NULL) {
+ /* Allocate the value stack */
+ ctxt->valueTab = (xmlXPathObjectPtr *)
+@@ -13942,11 +13941,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
+ "xmlXPathRunEval: last is less than zero\n");
+ return(-1);
+ }
++ oldDepth = ctxt->context->depth;
+ if (toBool)
+ return(xmlXPathCompOpEvalToBoolean(ctxt,
+ &comp->steps[comp->last], 0));
+ else
+ xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
++ ctxt->context->depth = oldDepth;
+
+ return(0);
+ }
+@@ -14217,6 +14218,7 @@ xmlXPathCompExprPtr
+ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
+ xmlXPathParserContextPtr pctxt;
+ xmlXPathCompExprPtr comp;
++ int oldDepth = 0;
+
+ #ifdef XPATH_STREAMING
+ comp = xmlXPathTryStreamCompile(ctxt, str);
+@@ -14230,8 +14232,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
+ if (pctxt == NULL)
+ return NULL;
+ if (ctxt != NULL)
+- ctxt->depth = 0;
++ oldDepth = ctxt->depth;
+ xmlXPathCompileExpr(pctxt, 1);
++ if (ctxt != NULL)
++ ctxt->depth = oldDepth;
+
+ if( pctxt->error != XPATH_EXPRESSION_OK )
+ {
+@@ -14252,8 +14256,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
+ comp = pctxt->comp;
+ if ((comp->nbStep > 1) && (comp->last >= 0)) {
+ if (ctxt != NULL)
+- ctxt->depth = 0;
++ oldDepth = ctxt->depth;
+ xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]);
++ if (ctxt != NULL)
++ ctxt->depth = oldDepth;
+ }
+ pctxt->comp = NULL;
+ }
+@@ -14409,6 +14415,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
+ #ifdef XPATH_STREAMING
+ xmlXPathCompExprPtr comp;
+ #endif
++ int oldDepth = 0;
+
+ if (ctxt == NULL) return;
+
+@@ -14422,8 +14429,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
+ #endif
+ {
+ if (ctxt->context != NULL)
+- ctxt->context->depth = 0;
++ oldDepth = ctxt->context->depth;
+ xmlXPathCompileExpr(ctxt, 1);
++ if (ctxt->context != NULL)
++ ctxt->context->depth = oldDepth;
+ CHECK_ERROR;
+
+ /* Check for trailing characters. */
+@@ -14432,9 +14441,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
+
+ if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) {
+ if (ctxt->context != NULL)
+- ctxt->context->depth = 0;
++ oldDepth = ctxt->context->depth;
+ xmlXPathOptimizeExpression(ctxt,
+ &ctxt->comp->steps[ctxt->comp->last]);
++ if (ctxt->context != NULL)
++ ctxt->context->depth = oldDepth;
+ }
+ }
+
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-08-25 13:37:46.000000000 +0200
+++ libxml2-2.12.7+dfsg+really2.9.14/debian/patches/series 2025-10-11 14:55:59.000000000 +0200
@@ -25,3 +25,4 @@
CVE-2025-49794_49796.patch
CVE-2025-6170.patch
CVE-2025-7425.patch
+CVE-2025-9714.patch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/debian-xml-sgml-pkgs/attachments/20251011/19ac3ca7/attachment-0001.sig>
More information about the debian-xml-sgml-pkgs
mailing list