Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: libxml2.9@packages.debian.org, security@debian.org Control: affects -1 + src:libxml2.9 User: release.debian.org@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.
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@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@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
Attachment:
signature.asc
Description: PGP signature