[meta-lts-collab][kirkstone][PATCH] expat: Fix CVEs
Jackson James <[email protected]> Mon, 22 Jun 2026 11:14:25 +0530
| Newsgroups | org.yoctoproject.lists.yocto-patches |
|---|---|
| Message-ID | <[email protected]> |
Fix the following CVEs- CVE-2026-32776 CVE-2026-32777 CVE-2026-32778 Signed-off-by: Jackson James <[email protected]> --- .../expat/expat/CVE-2026-32776.patch | 51 +++++++++++ .../expat/expat/CVE-2026-32777.patch | 48 ++++++++++ .../expat/expat/CVE-2026-32778.patch | 91 +++++++++++++++++++ meta-core/recipes-core/expat/expat_%.bbappend | 7 ++ 4 files changed, 197 insertions(+) create mode 100644 meta-core/recipes-core/expat/expat/CVE-2026-32776.patch create mode 100644 meta-core/recipes-core/expat/expat/CVE-2026-32777.patch create mode 100644 meta-core/recipes-core/expat/expat/CVE-2026-32778.patch create mode 100644 meta-core/recipes-core/expat/expat_%.bbappend diff --git a/meta-core/recipes-core/expat/expat/CVE-2026-32776.patch b/meta-core/recipes-core/expat/expat/CVE-2026-32776.patch new file mode 100644 index 0000000..0b96fbc --- /dev/null +++ b/meta-core/recipes-core/expat/expat/CVE-2026-32776.patch @@ -0,0 +1,51 @@ +From 5be25657583ea91b09025c858b4785834c20f59c Mon Sep 17 00:00:00 2001 +From: Francesco Bertolaccini <[email protected]> +Date: Tue, 3 Mar 2026 16:41:43 +0100 +Subject: [PATCH] Fix NULL function-pointer dereference for empty external + parameter entities + +When an external parameter entity with empty text is referenced inside +an entity declaration value, the sub-parser created to handle it receives +0 bytes of input. Processing enters entityValueInitProcessor which calls +storeEntityValue() with the parser's encoding; since no bytes were ever +processed, encoding detection has not yet occurred and the encoding is +still the initial probing encoding set up by XmlInitEncoding(). That +encoding only populates scanners[] (for prolog and content), not +literalScanners[]. XmlEntityValueTok() calls through +literalScanners[XML_ENTITY_VALUE_LITERAL] which is NULL, causing a +SEGV. + +Skip the tokenization loop entirely when entityTextPtr >= entityTextEnd, +and initialize the `next` pointer before the early exit so that callers +(callStoreEntityValue) receive a valid value through nextPtr. + +CVE: CVE-2026-32776 +Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/5be25657583ea91b09025c858b4785834c20f59c] + +Comment: Patch is refreshed as per codebase of 2.5.0 +Signed-off-by: Jackson James <[email protected]> +--- + lib/xmlparse.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 0883e2e..6a9ab7d 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -6194,6 +6194,13 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc, + for (;;) { + const char *next + = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ ++ ++ /* Nothing to tokenize. */ ++ if (entityTextPtr >= entityTextEnd) { ++ result = XML_ERROR_NONE; ++ goto endEntityValue; ++ } ++ + int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); + + if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, +-- +2.34.1 + diff --git a/meta-core/recipes-core/expat/expat/CVE-2026-32777.patch b/meta-core/recipes-core/expat/expat/CVE-2026-32777.patch new file mode 100644 index 0000000..687e2e4 --- /dev/null +++ b/meta-core/recipes-core/expat/expat/CVE-2026-32777.patch @@ -0,0 +1,48 @@ +From 55cda8c7125986e17d7e1825cba413bd94a35d02 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping <[email protected]> +Date: Sun, 1 Mar 2026 20:16:13 +0100 +Subject: [PATCH] lib: Reject XML_TOK_INSTANCE_START infinite loop in + entityValueProcessor + +.. that OSS-Fuzz/ClusterFuzz uncovered + +CVE: CVE-2026-32777 +Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/55cda8c7125986e17d7e1825cba413bd94a35d02] + +Comment: Patch is refreshed as per codebase of 2.5.0 +Signed-off-by: Jackson James <[email protected]> +--- + lib/xmlparse.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 6a9ab7d..c7e3665 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -4560,7 +4560,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, + } + /* If we get this token, we have the start of what might be a + normal tag, but not a declaration (i.e. it doesn't begin with +- "<!"). In a DTD context, that isn't legal. ++ "<!" or "<?"). In a DTD context, that isn't legal. + */ + else if (tok == XML_TOK_INSTANCE_START) { + *nextPtr = next; +@@ -4649,6 +4649,14 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end, + /* found end of entity value - can store it now */ + return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); + } ++ /* If we get this token, we have the start of what might be a ++ normal tag, but not a declaration (i.e. it doesn't begin with ++ "<!" or "<?"). In a DTD context, that isn't legal. ++ */ ++ else if (tok == XML_TOK_INSTANCE_START) { ++ *nextPtr = next; ++ return XML_ERROR_SYNTAX; ++ } + start = next; + } + } +-- +2.34.1 + diff --git a/meta-core/recipes-core/expat/expat/CVE-2026-32778.patch b/meta-core/recipes-core/expat/expat/CVE-2026-32778.patch new file mode 100644 index 0000000..fb2d021 --- /dev/null +++ b/meta-core/recipes-core/expat/expat/CVE-2026-32778.patch @@ -0,0 +1,91 @@ +From 576b61e42feeea704253cb7c7bedb2eeb3754387 Mon Sep 17 00:00:00 2001 +From: laserbear <[email protected]> +Date: Sun, 8 Mar 2026 17:28:06 -0700 +Subject: [PATCH] copy prefix name to pool before lookup + +.. so that we cannot end up with a zombie PREFIX in the pool +that has NULL for a name. + +Co-authored-by: Sebastian Pipping <[email protected]> + +CVE: CVE-2026-32778 +Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/576b61e42feeea704253cb7c7bedb2eeb3754387] + +Comment: Patch is refreshed as per codebase of 2.5.0 +Signed-off-by: Jackson James <[email protected]> +--- + lib/xmlparse.c | 42 ++++++++++++++++++++++++++++++++++-------- + 1 file changed, 34 insertions(+), 8 deletions(-) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index c7e3665..7579a1d 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -556,6 +556,8 @@ static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, + static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); + static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, + const XML_Char *s); ++static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool, ++ const XML_Char *s); + static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, + int n); + static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, +@@ -6783,16 +6785,23 @@ setContext(XML_Parser parser, const XML_Char *context) { + else { + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_FALSE; +- prefix +- = (PREFIX *)lookup(parser, &dtd->prefixes, +- poolStart(&parser->m_tempPool), sizeof(PREFIX)); +- if (! prefix) ++ const XML_Char *const prefixName = poolCopyStringNoFinish( ++ &dtd->pool, poolStart(&parser->m_tempPool)); ++ if (! prefixName) { + return XML_FALSE; +- if (prefix->name == poolStart(&parser->m_tempPool)) { +- prefix->name = poolCopyString(&dtd->pool, prefix->name); +- if (! prefix->name) +- return XML_FALSE; + } ++ ++ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, prefixName, ++ sizeof(PREFIX)); ++ ++ const bool prefixNameUsed = prefix && prefix->name == prefixName; ++ if (prefixNameUsed) ++ poolFinish(&dtd->pool); ++ else ++ poolDiscard(&dtd->pool); ++ ++ if (! prefix) ++ return XML_FALSE; + poolDiscard(&parser->m_tempPool); + } + for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); +@@ -7381,6 +7390,23 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) { + return s; + } + ++// A version of `poolCopyString` that does not call `poolFinish` ++// and reverts any partial advancement upon failure. ++static const XML_Char *FASTCALL ++poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) { ++ const XML_Char *const original = s; ++ do { ++ if (! poolAppendChar(pool, *s)) { ++ // Revert any previously successful advancement ++ const ptrdiff_t advancedBy = s - original; ++ if (advancedBy > 0) ++ pool->ptr -= advancedBy; ++ return NULL; ++ } ++ } while (*s++); ++ return pool->start; ++} ++ + static const XML_Char * + poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { + if (! pool->ptr && ! poolGrow(pool)) { +-- +2.34.1 + diff --git a/meta-core/recipes-core/expat/expat_%.bbappend b/meta-core/recipes-core/expat/expat_%.bbappend new file mode 100644 index 0000000..0a11912 --- /dev/null +++ b/meta-core/recipes-core/expat/expat_%.bbappend @@ -0,0 +1,7 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" + +SRC_URI:append = " \ + file://CVE-2026-32776.patch \ + file://CVE-2026-32777.patch \ + file://CVE-2026-32778.patch \ +" -- 2.34.1