diff mbox series

[wrynose,3/3] expat: fix CVE-2026-118370

Message ID 20261105091719.1622520-3-dkelaiya@cisco.com
State New
Headers show
Series [wrynose,1/3] expat: fix CVE-2026-113351 | expand

Commit Message

From: Darsh Kelaiya <dkelaiya@cisco.com>

Backport the upstream prefix and attribute-index fixes [1,2]
identified by the release announcement [3]. Use size_t for storeAtts
bookkeeping and reject values that cannot be represented by the
existing public int attribute-count interfaces.

Include the related tokenizer-count correction [4] so XmlGetAttributes
and getAtts do not overflow a signed count or narrow the available
attribute capacity before the storeAtts checks. This closes the same
large-attribute data path; it corrects a pre-existing issue rather than
a regression introduced by the first two fixes. Preserve Expat 2.8.3's
PTRCALL annotations on the tokenizer callback and implementation.

Validated with the full native unit suite, inline undefined-behavior
traps and an arithmetic boundary model. A multi-gigabyte attribute
payload and BitBake were not run.

[1] https://github.com/libexpat/libexpat/commit/621cb2c78b253ee023a86bc91d6ddb048481c04c
[2] https://github.com/libexpat/libexpat/commit/1bac53c4fc460a03cd9860f39501c7979f6750ae
[3] https://www.openwall.com/lists/oss-security/2026/11/02/6
[4] https://github.com/libexpat/libexpat/commit/c67cbc6185d1b494f521f2f46280d5982f50f2cf

Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
 .../expat/expat/CVE-2026-118370_p1.patch      | 29 +++++++
 .../expat/expat/CVE-2026-118370_p2.patch      | 58 ++++++++++++++
 .../expat/expat/CVE-2026-118370_p3.patch      | 77 +++++++++++++++++++
 meta/recipes-core/expat/expat_2.8.3.bb        |  3 +
 4 files changed, 167 insertions(+)
 create mode 100644 meta/recipes-core/expat/expat/CVE-2026-118370_p1.patch
 create mode 100644 meta/recipes-core/expat/expat/CVE-2026-118370_p2.patch
 create mode 100644 meta/recipes-core/expat/expat/CVE-2026-118370_p3.patch
diff mbox series

Patch

diff --git a/meta/recipes-core/expat/expat/CVE-2026-118370_p1.patch b/meta/recipes-core/expat/expat/CVE-2026-118370_p1.patch
new file mode 100644
index 0000000000..0b2e5f48d6
--- /dev/null
+++ b/meta/recipes-core/expat/expat/CVE-2026-118370_p1.patch
@@ -0,0 +1,29 @@ 
+From 621cb2c78b253ee023a86bc91d6ddb048481c04c Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+Date: Tue, 27 Oct 2026 17:57:19 +0100
+Subject: [PATCH] lib: Protect `nPrefixes` in `storeAtts` from signed integer
+ overflow
+
+.. by migrating to `size_t`
+
+CVE: CVE-2026-118370
+Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/621cb2c78b253ee023a86bc91d6ddb048481c04c]
+
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ lib/xmlparse.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index b17f5e0..6fdfbc8 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -3871,7 +3871,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
+   int attIndex = 0;
+   XML_Char *uri;
+-  int nPrefixes = 0;
++  size_t nPrefixes = 0;
+   BINDING *binding;
+   const XML_Char *localPart;
+ 
diff --git a/meta/recipes-core/expat/expat/CVE-2026-118370_p2.patch b/meta/recipes-core/expat/expat/CVE-2026-118370_p2.patch
new file mode 100644
index 0000000000..0015f4f1cd
--- /dev/null
+++ b/meta/recipes-core/expat/expat/CVE-2026-118370_p2.patch
@@ -0,0 +1,58 @@ 
+From 1bac53c4fc460a03cd9860f39501c7979f6750ae Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+Date: Tue, 27 Oct 2026 15:20:33 +0100
+Subject: [PATCH] lib: Protect `attIndex` in `storeAtts` from signed integer
+ overflow
+
+.. by migrating to `size_t`
+
+CVE: CVE-2026-118370
+Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/1bac53c4fc460a03cd9860f39501c7979f6750ae]
+
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ lib/xmlparse.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 6fdfbc8..6c97639 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -3869,7 +3869,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+           TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
+           enum XML_Account account) {
+   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
+-  int attIndex = 0;
++  size_t attIndex = 0;
+   XML_Char *uri;
+   size_t nPrefixes = 0;
+   BINDING *binding;
+@@ -4048,11 +4048,16 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+   }
+ 
+   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
+-  parser->m_nSpecifiedAtts = attIndex;
++  // Detect and reject integer overflow
++  if (attIndex > INT_MAX)
++    return XML_ERROR_NO_MEMORY;
++  parser->m_nSpecifiedAtts = (int)attIndex;
+   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+-    for (int i = 0; i < attIndex; i += 2)
++    for (size_t i = 0; i < attIndex; i += 2)
+       if (appAtts[i] == elementType->idAtt->name) {
+-        parser->m_idAttIndex = i;
++        if (i > INT_MAX)
++          return XML_ERROR_NO_MEMORY;
++        parser->m_idAttIndex = (int)i;
+         break;
+       }
+   } else
+@@ -4085,7 +4090,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+ 
+   /* expand prefixed attribute names, check for duplicates,
+      and clear flags that say whether attributes were specified */
+-  int i = 0;
++  size_t i = 0;
+   if (nPrefixes) {
+     unsigned int j; /* hash table index */
+     unsigned long version = parser->m_nsAttsVersion;
diff --git a/meta/recipes-core/expat/expat/CVE-2026-118370_p3.patch b/meta/recipes-core/expat/expat/CVE-2026-118370_p3.patch
new file mode 100644
index 0000000000..2ad72abee6
--- /dev/null
+++ b/meta/recipes-core/expat/expat/CVE-2026-118370_p3.patch
@@ -0,0 +1,77 @@ 
+From c67cbc6185d1b494f521f2f46280d5982f50f2cf Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+Date: Fri, 30 Oct 2026 18:37:11 +0100
+Subject: [PATCH] lib: Fix integer truncation in `XmlGetAttributes`/`getAtts`
+
+CVE: CVE-2026-118370
+Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/c67cbc6185d1b494f521f2f46280d5982f50f2cf]
+
+Backport Changes:
+- Retain PTRCALL on the getAtts callback and implementation for Expat
+  2.8.3 calling-convention compatibility, and align the callback
+  continuation with the retained annotation.
+
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ lib/xmlparse.c    | 5 ++---
+ lib/xmltok.h      | 4 ++--
+ lib/xmltok_impl.c | 6 +++---
+ 3 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 6c97639..2a4e47b 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -3898,8 +3898,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+     return XML_ERROR_NO_MEMORY;
+ 
+   /* get the attributes from the tokenizer */
+-  size_t n = (size_t)XmlGetAttributes(enc, attStr, (int)parser->m_attsSize,
+-                                      parser->m_atts);
++  size_t n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
+ 
+   /* Detect and prevent integer overflow */
+   if (n > SIZE_MAX - nDefaultAtts) {
+@@ -3949,7 +3948,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+       /* Detect and prevent integer overflow. */
+       if (n > (size_t)INT_MAX)
+         return XML_ERROR_NO_MEMORY;
+-      XmlGetAttributes(enc, attStr, (int)n, parser->m_atts);
++      XmlGetAttributes(enc, attStr, n, parser->m_atts);
+     }
+   }
+ 
+diff --git a/lib/xmltok.h b/lib/xmltok.h
+index bd868b8..4be6fdc 100644
+--- a/lib/xmltok.h
++++ b/lib/xmltok.h
+@@ -180,8 +180,8 @@ struct encoding {
+                                  const char *);
+   int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+   const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
+-  int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+-                        ATTRIBUTE *atts);
++  size_t(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, size_t attsMax,
++                           ATTRIBUTE *atts);
+   int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+   int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
+                                      const char *);
+diff --git a/lib/xmltok_impl.c b/lib/xmltok_impl.c
+index 2719e06..3955285 100644
+--- a/lib/xmltok_impl.c
++++ b/lib/xmltok_impl.c
+@@ -1504,11 +1504,11 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+    first attsMax attributes are stored in atts.
+ */
+ 
+-static int PTRCALL
+-PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
++static size_t PTRCALL
++PREFIX(getAtts)(const ENCODING *enc, const char *ptr, size_t attsMax,
+                 ATTRIBUTE *atts) {
+   enum { other, inName, inValue } state = inName;
+-  int nAtts = 0;
++  size_t nAtts = 0;
+   int open = 0; /* defined when state == inValue;
+                    initialization just to shut up compilers */
+ 
diff --git a/meta/recipes-core/expat/expat_2.8.3.bb b/meta/recipes-core/expat/expat_2.8.3.bb
index b6911e79de..89ec156e92 100644
--- a/meta/recipes-core/expat/expat_2.8.3.bb
+++ b/meta/recipes-core/expat/expat_2.8.3.bb
@@ -27,6 +27,9 @@  SRC_URI = "${GITHUB_BASE_URI}/download/R_${VERSION_TAG}/expat-${PV}.tar.bz2 \
            file://CVE-2026-113351_p5.patch \
            file://CVE-2026-117610_p1.patch \
            file://CVE-2026-117610_p2.patch \
+           file://CVE-2026-118370_p1.patch \
+           file://CVE-2026-118370_p2.patch \
+           file://CVE-2026-118370_p3.patch \
            "
 
 GITHUB_BASE_URI = "https://github.com/libexpat/libexpat/releases/"