Your message dated Sat, 10 Jan 2026 11:59:46 +0000
with message-id <[email protected]>
and subject line Released with 12.13
has caused the Debian Bug report #1117844,
regarding bookworm-pu: package libxml2/2.9.14+dfsg-1.3~deb12u5
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1117844: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1117844
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:libxml2.9
User: [email protected]
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.9.14+dfsg-1.3~deb12u4.

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 oldstable
  [*] 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.9.14+dfsg libxml2-2.9.14+dfsg

 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.9.14+dfsg/debian/changelog 
libxml2-2.9.14+dfsg/debian/changelog
--- libxml2-2.9.14+dfsg/debian/changelog        2025-08-25 13:30:10.000000000 
+0200
+++ libxml2-2.9.14+dfsg/debian/changelog        2025-10-11 14:41:17.000000000 
+0200
@@ -1,3 +1,12 @@
+libxml2 (2.9.14+dfsg-1.3~deb12u5) bookworm; 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 <[email protected]>  Sat, 11 Oct 2025 14:41:17 +0200
+
 libxml2 (2.9.14+dfsg-1.3~deb12u4) bookworm-security; urgency=high
 
   * CVE-2025-7425: heap-use-after-free in xmlFreeID caused by `atype`
diff -Nru libxml2-2.9.14+dfsg/debian/patches/CVE-2025-7425.patch 
libxml2-2.9.14+dfsg/debian/patches/CVE-2025-7425.patch
--- libxml2-2.9.14+dfsg/debian/patches/CVE-2025-7425.patch      2025-08-25 
13:29:44.000000000 +0200
+++ libxml2-2.9.14+dfsg/debian/patches/CVE-2025-7425.patch      2025-10-11 
14:41:17.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 60cc6f4..2ce9f7e 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.9.14+dfsg/debian/patches/CVE-2025-9714.patch 
libxml2-2.9.14+dfsg/debian/patches/CVE-2025-9714.patch
--- libxml2-2.9.14+dfsg/debian/patches/CVE-2025-9714.patch      1970-01-01 
01:00:00.000000000 +0100
+++ libxml2-2.9.14+dfsg/debian/patches/CVE-2025-9714.patch      2025-10-11 
14:41:17.000000000 +0200
@@ -0,0 +1,113 @@
+From: Nick Wellnhofer <[email protected]>
+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.9.14+dfsg/debian/patches/series 
libxml2-2.9.14+dfsg/debian/patches/series
--- libxml2-2.9.14+dfsg/debian/patches/series   2025-08-25 13:25:27.000000000 
+0200
+++ libxml2-2.9.14+dfsg/debian/patches/series   2025-10-11 14:41:17.000000000 
+0200
@@ -24,3 +24,4 @@
 CVE-2025-6170.patch
 CVE-2025-49794_CVE-2025-49796.patch
 CVE-2025-7425.patch
+CVE-2025-9714.patch

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Package: release.debian.org\nVersion: 12.13\n\nThis update has been released as 
part of Debian 12.13.

--- End Message ---

Reply via email to