new file mode 100644
@@ -0,0 +1,51 @@
+From 5be25657583ea91b09025c858b4785834c20f59c Mon Sep 17 00:00:00 2001
+From: Francesco Bertolaccini <francesco.bertolaccini@trailofbits.com>
+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 <jacksonj2@kpit.com>
+---
+ 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
+
new file mode 100644
@@ -0,0 +1,48 @@
+From 55cda8c7125986e17d7e1825cba413bd94a35d02 Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+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 <jacksonj2@kpit.com>
+---
+ 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
+
new file mode 100644
@@ -0,0 +1,91 @@
+From 576b61e42feeea704253cb7c7bedb2eeb3754387 Mon Sep 17 00:00:00 2001
+From: laserbear <10689391+Laserbear@users.noreply.github.com>
+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 <sebastian@pipping.org>
+
+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 <jacksonj2@kpit.com>
+---
+ 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
+
new file mode 100644
@@ -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 \
+"
Fix the following CVEs- CVE-2026-32776 CVE-2026-32777 CVE-2026-32778 Signed-off-by: Jackson James <jacksonj2@kpit.com> --- .../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