> -----Original Message-----
> From: Yoann Congal <[email protected]>
> Sent: Friday, May 8, 2026 12:36 AM
> To: Marko, Peter (FT D EU SK BFS1) <[email protected]>;
> [email protected]
> Subject: Re: [OE-core] [scarthgap][PATCH] expat: patch CVE-2026-41080
>
> On Tue May 5, 2026 at 10:52 PM CEST, Peter Marko via lists.openembedded.org
> wrote:
> > From: Peter Marko <[email protected]>
> >
> > Pick github PR [1] mentioned in [2].
> > *
> 969af8f4654ce50d837bb9199a73d1d02d2c7e16..4ba09dc471b39a78d77e5179d0243
> 186c0c4ff7a
> > * dropped code which doesn't exist in 2.6.4 yet (github actions, map
> > file)
> > * resolved minor conflicts (formatting)
> > * picked 2 additional commits to apply the code cleanly
> >
> > [1] https://github.com/libexpat/libexpat/pull/1183
> > [2] https://security-tracker.debian.org/tracker/CVE-2026-41080
> >
> > Signed-off-by: Peter Marko <[email protected]>
> > ---
> > .../expat/expat/CVE-2026-41080-01.patch | 50 ++
> > .../expat/expat/CVE-2026-41080-02.patch | 29 ++
> > .../expat/expat/CVE-2026-41080-03.patch | 467 ++++++++++++++++++
> > meta/recipes-core/expat/expat_2.6.4.bb | 3 +
> > 4 files changed, 549 insertions(+)
> > create mode 100644 meta/recipes-core/expat/expat/CVE-2026-41080-01.patch
> > create mode 100644 meta/recipes-core/expat/expat/CVE-2026-41080-02.patch
> > create mode 100644 meta/recipes-core/expat/expat/CVE-2026-41080-03.patch
> >
> > diff --git a/meta/recipes-core/expat/expat/CVE-2026-41080-01.patch
> b/meta/recipes-core/expat/expat/CVE-2026-41080-01.patch
> > new file mode 100644
> > index 00000000000..0c6af75a5de
> > --- /dev/null
> > +++ b/meta/recipes-core/expat/expat/CVE-2026-41080-01.patch
> > @@ -0,0 +1,50 @@
> > +From fe04a7f0ff8afe57ba33d919f368b1ba23bcda92 Mon Sep 17 00:00:00 2001
> > +From: Sebastian Pipping <[email protected]>
> > +Date: Sun, 30 Mar 2025 19:26:55 +0200
> > +Subject: [PATCH 1/3] lib/xmlparse.c: Address clang-tidy warning
> > + misc-no-recursion
> > +
> > +CVE: CVE-2026-41080
> > +Upstream-Status: Backport
> [https://github.com/libexpat/libexpat/commit/fe04a7f0ff8afe57ba33d919f368b1ba23bcd
> a92]
> > +Signed-off-by: Peter Marko <[email protected]>
> > +---
> > + lib/xmlparse.c | 17 ++++++++++-------
> > + 1 file changed, 10 insertions(+), 7 deletions(-)
> > +
> > +diff --git a/lib/xmlparse.c b/lib/xmlparse.c
> > +index 9bc67f38..cb25c37b 100644
> > +--- a/lib/xmlparse.c
> > ++++ b/lib/xmlparse.c
> > +@@ -1243,9 +1243,10 @@ generate_hash_secret_salt(XML_Parser parser) {
> > +
> > + static unsigned long
> > + get_hash_secret_salt(XML_Parser parser) {
> > +- if (parser->m_parentParser != NULL)
> > +- return get_hash_secret_salt(parser->m_parentParser);
> > +- return parser->m_hash_secret_salt;
> > ++ const XML_Parser rootParser = getRootParserOf(parser, NULL);
> > ++ assert(! rootParser->m_parentParser);
> > ++
> > ++ return rootParser->m_hash_secret_salt;
> > + }
> > +
> > + static enum XML_Error
> > +@@ -2321,12 +2322,14 @@ int XMLCALL
> > + XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
> > + if (parser == NULL)
> > + return 0;
> > +- if (parser->m_parentParser)
> > +- return XML_SetHashSalt(parser->m_parentParser, hash_salt);
> > ++
> > ++ const XML_Parser rootParser = getRootParserOf(parser, NULL);
> > ++ assert(! rootParser->m_parentParser);
> > ++
> > + /* block after XML_Parse()/XML_ParseBuffer() has been called */
> > +- if (parserBusy(parser))
> > ++ if (parserBusy(rootParser))
> > + return 0;
> > +- parser->m_hash_secret_salt = hash_salt;
> > ++ rootParser->m_hash_secret_salt = hash_salt;
> > + return 1;
> > + }
> > +
> > diff --git a/meta/recipes-core/expat/expat/CVE-2026-41080-02.patch
> b/meta/recipes-core/expat/expat/CVE-2026-41080-02.patch
> > new file mode 100644
> > index 00000000000..953f93c68a9
> > --- /dev/null
> > +++ b/meta/recipes-core/expat/expat/CVE-2026-41080-02.patch
> > @@ -0,0 +1,29 @@
> > +From 7fb2c7a454edc9e2880073a27f899c31d9b078ce Mon Sep 17 00:00:00 2001
> > +From: Atrem Borovik <[email protected]>
> > +Date: Sat, 20 Dec 2025 13:22:16 +0300
> > +Subject: [PATCH 2/3] WASI: remove getpid
> > +
> > +CVE: CVE-2026-41080
> > +Upstream-Status: Backport
> [https://github.com/libexpat/libexpat/commit/7fb2c7a454edc9e2880073a27f899c31d9b
> 078ce]
> > +Signed-off-by: Peter Marko <[email protected]>
> > +---
> > + lib/xmlparse.c | 5 ++++-
> > + 1 file changed, 4 insertions(+), 1 deletion(-)
> > +
> > +diff --git a/lib/xmlparse.c b/lib/xmlparse.c
> > +index cb25c37b..1bafb948 100644
> > +--- a/lib/xmlparse.c
> > ++++ b/lib/xmlparse.c
> > +@@ -1228,8 +1228,11 @@ generate_hash_secret_salt(XML_Parser parser) {
> > + # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
> > + /* .. and self-made low quality for backup: */
> > +
> > ++ entropy = gather_time_entropy();
> > ++# if ! defined(__wasi__)
> > + /* Process ID is 0 bits entropy if attacker has local access */
> > +- entropy = gather_time_entropy() ^ getpid();
> > ++ entropy ^= getpid();
> > ++# endif
> > +
> > + /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
> > + if (sizeof(unsigned long) == 4) {
> > diff --git a/meta/recipes-core/expat/expat/CVE-2026-41080-03.patch
> b/meta/recipes-core/expat/expat/CVE-2026-41080-03.patch
> > new file mode 100644
> > index 00000000000..4d17f1a0b0e
> > --- /dev/null
> > +++ b/meta/recipes-core/expat/expat/CVE-2026-41080-03.patch
> > @@ -0,0 +1,467 @@
> > +From b77ab600e1893fdcfc3868d0a46efcc87c87943d Mon Sep 17 00:00:00 2001
> > +From: Sebastian Pipping <[email protected]>
> > +Date: Wed, 8 Apr 2026 15:41:54 +0200
> > +Subject: [PATCH 3/3] [CVE-2026-41080] Improve protection against hash
> > flooding
> > + (fixes #47)
> > +
> > +Fixes #47
> > +
> > +CVE: CVE-2026-41080
> > +Upstream-Status: Backport [https://github.com/libexpat/libexpat/pull/1183]
> > +Signed-off-by: Peter Marko <[email protected]>
> > +---
> > + Changes | 16 ++++++
> > + doc/reference.html | 51 ++++++++++++++--
> > + lib/expat.h | 12 ++++
> > + lib/internal.h | 2 +
> > + lib/xmlparse.c | 118 ++++++++++++++++++++++++++------------
> > + tests/basic_tests.c | 25 ++++++++
> > + 6 files changed, 181 insertions(+), 43 deletions(-)
> > +
> > +diff --git a/Changes b/Changes
> > +index 4265d608..1d87d6a0 100644
> > +--- a/Changes
> > ++++ b/Changes
> > +@@ -30,6 +30,22 @@
> > +
> > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> > +
> > + Patches:
> > ++ Security fixes:
> > ++ #47 #1183 CVE-2026-41080 -- The existing hash flooding protection
> > ++ (based on SipHash) only used 4 to 8 bytes of entropy
> > for
> > ++ a salt, when 16 bytes of salt are supported by the
> > ++ implementation of SipHash used by Expat. Now full 16
> > bytes
> > ++ of entropy are used to improve protection against hash
> > ++ flooding attacks.
> > ++ Existing API function XML_SetHashSalt is now
> > deprecated
> > ++ because of its limitations, and its use should be
> > ++ considered a vulnerability. Please either use the new
> > API
> > ++ function XML_SetHashSalt16Bytes (with
> > known-high-quality
> > ++ entropy input only!) instead, or leave the derivation
> > of
> > ++ a 16-bytes hash salt from high quality entropy to
> > Expat's
> > ++ internal machinery (by *not* calling either of the two
> > ++ XML_SetHashSalt* functions).
> > ++
>
> Hello Peter,
>
> I don't know if we can consider CVE-2026-41080 "fixed" with this. A code
> calling the existing XML_SetHashSalt function will keep be vulnerable
> even with this patch...
>
> Maybe we can apply this but leave the CVE applicable to let downstream
> users review their expat calls?
>
> This might be one of the rare case to use
> CVE_STATUS[CVE-2026-41080] = "vulnerable-investigating: ..."
> to grab attention of users?
>
Hello Yoann,
I don't really like that idea.
What’s the difference to master where the same patch (included in release
upgrade) marks it as patched?
Peter
> Thanks!
>
> > + Security fixes:
> > + #1018 #1034 CVE-2025-59375 -- Disallow use of disproportional
> > amounts of
> > + dynamic memory from within an Expat parser (e.g.
> > previously
> > +diff --git a/doc/reference.html b/doc/reference.html
> > +index 8f14b011..7f374f84 100644
> > +--- a/doc/reference.html
> > ++++ b/doc/reference.html
> > +@@ -174,7 +174,8 @@ interface.</p>
> > + <li><a href="#XML_GetAttributeInfo">XML_GetAttributeInfo</a></li>
> > + <li><a href="#XML_SetEncoding">XML_SetEncoding</a></li>
> > + <li><a
> href="#XML_SetParamEntityParsing">XML_SetParamEntityParsing</a></li>
> > +- <li><a href="#XML_SetHashSalt">XML_SetHashSalt</a></li>
> > ++ <li><a href="#XML_SetHashSalt">XML_SetHashSalt</a> (deprecated)</li>
> > ++ <li><a
> href="#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></li>
> > + <li><a href="#XML_UseForeignDTD">XML_UseForeignDTD</a></li>
> > + <li><a
> > href="#XML_SetReturnNSTriplet">XML_SetReturnNSTriplet</a></li>
> > + <li><a href="#XML_DefaultCurrent">XML_DefaultCurrent</a></li>
> > +@@ -2553,10 +2554,10 @@ The choices for <code>code</code> are:
> > + no effect and will always return 0.
> > + </div>
> > +
> > +-<h4 id="XML_SetHashSalt">XML_SetHashSalt</h4>
> > ++<h4 id="XML_SetHashSalt">XML_SetHashSalt (deprecated)</h4>
> > + <pre class="fcndec">
> > + int XMLCALL
> > +-XML_SetHashSalt(XML_Parser p,
> > ++XML_SetHashSalt(XML_Parser parser,
> > + unsigned long hash_salt);
> > + </pre>
> > + <div class="fcndef">
> > +@@ -2564,15 +2565,55 @@ Sets the hash salt to use for internal hash
> calculations.
> > + Helps in preventing DoS attacks based on predicting hash
> > + function behavior. In order to have an effect this must be called
> > + before parsing has started. Returns 1 if successful, 0 when called
> > +-after <code>XML_Parse</code> or <code>XML_ParseBuffer</code>.
> > ++after <code>XML_Parse</code> or <code>XML_ParseBuffer</code> or when
> > ++ <code>parser</code> is <code>NULL</code>.
> > ++ <p>
> > ++ <b>Note:</b> Function <code>XML_SetHashSalt</code> is
> > ++ <strong>deprecated</strong>. Please use function <code><a href=
> > ++ "#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></code>
> instead for better
> > ++ security. <code>XML_SetHashSalt</code> only provides 4 to 8
> > bytes of
> entropy
> > ++ (depending on the size of type <code>unsigned long</code>)
> > while the
> SipHash
> > ++ implementation used by Expat can leverage up to 16 bytes of
> > entropy — at
> least
> > ++ twice as much. Function <code><a href=
> > ++ "#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></code> of
> Expat >=2.7.6
> > ++ (and where backported) matches the amount of entropy supported
> > by
> SipHash.
> > ++ </p>.
> > + <p><b>Note:</b> This call is optional, as the parser will auto-generate
> > +-a new random salt value if no value has been set at the start of
> > parsing.</p>
> > ++a new random salt value internally if no value has been set by the start
> > of
> parsing.</p>
> > + <p><b>Note:</b> One should not call <code>XML_SetHashSalt</code> with a
> > + hash salt value of 0, as this value is used as sentinel value to indicate
> > + that <code>XML_SetHashSalt</code> has <b>not</b> been called.
> Consequently
> > + such a call will have no effect, even if it returns 1.</p>
> > + </div>
> > +
> > ++ <h4 id="XML_SetHashSalt16Bytes">
> > ++ XML_SetHashSalt16Bytes
> > ++ </h4>
> > ++
> > ++ <pre class="fcndec">
> > ++/* Added in Expat 2.7.6. */
> > ++XML_Bool XMLCALL
> > ++XML_SetHashSalt16Bytes(XML_Parser parser,
> > ++ const uint8_t entropy[16]);
> > ++</pre>
> > ++ <div class="fcndef">
> > ++ Sets the hash salt to use for internal hash calculations. Helps
> > in preventing
> DoS
> > ++ attacks based on predicting hash function behavior. In order to
> > have an
> effect
> > ++ this must be called before parsing has started. Returns
> <code>XML_TRUE</code> if
> > ++ successful, <code>XML_FALSE</code> when called after
> <code>XML_Parse</code> or
> > ++ <code>XML_ParseBuffer</code> or when <code>parser</code> is
> <code>NULL</code>.
> > ++ <p>
> > ++ <b>Note:</b> Setting a salt that is <em>not</em> from a source
> > of high
> quality
> > ++ entropy (like <code>getentropy(3)</code>) will make the parser
> vulnerable to
> > ++ hash flooding attacks.
> > ++ </p>
> > ++
> > ++ <p>
> > ++ <b>Note:</b> This call is optional, as the parser will
> > auto-generate a new
> > ++ random salt value internally if no value has been set by the
> > start of parsing.
> > ++ </p>
> > ++ </div>
> > ++
> > + <h4 id="XML_UseForeignDTD">XML_UseForeignDTD</h4>
> > + <pre class="fcndec">
> > + enum XML_Error XMLCALL
> > +diff --git a/lib/expat.h b/lib/expat.h
> > +index df207e9e..b356e002 100644
> > +--- a/lib/expat.h
> > ++++ b/lib/expat.h
> > +@@ -44,6 +44,7 @@
> > + #ifndef Expat_INCLUDED
> > + #define Expat_INCLUDED 1
> > +
> > ++# include <stdint.h> // for uint8_t
> > + #include <stdlib.h>
> > + #include "expat_external.h"
> > +
> > +@@ -916,10 +917,21 @@ XML_SetParamEntityParsing(XML_Parser parser,
> > + function behavior. This must be called before parsing is started.
> > + Returns 1 if successful, 0 when called after parsing has started.
> > + Note: If parser == NULL, the function will do nothing and return 0.
> > ++ DEPRECATED since Expat 2.7.6.
> > + */
> > + XMLPARSEAPI(int)
> > + XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
> > +
> > ++/* Sets the hash salt to use for internal hash calculations.
> > ++ Helps in preventing DoS attacks based on predicting hash function
> > behavior.
> > ++ This must be called before parsing is started.
> > ++ Returns XML_TRUE if successful, XML_FALSE when called after parsing has
> > ++ started or when parser is NULL.
> > ++ Added in Expat 2.7.6.
> > ++*/
> > ++XMLPARSEAPI(XML_Bool)
> > ++XML_SetHashSalt16Bytes(XML_Parser parser, const uint8_t entropy[16]);
> > ++
> > + /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR,
> then
> > + XML_GetErrorCode returns information about the error.
> > + */
> > +diff --git a/lib/internal.h b/lib/internal.h
> > +index 32faaa05..617d6454 100644
> > +--- a/lib/internal.h
> > ++++ b/lib/internal.h
> > +@@ -113,6 +113,7 @@
> > + #if defined(_WIN32)
> > \
> > + && (! defined(__USE_MINGW_ANSI_STDIO)
> > \
> > + || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
> > ++# define EXPAT_FMT_LLX(midpart) "%" midpart "I64x"
> > + # define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
> > + # if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for
> > MinGW
> > + # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
> > +@@ -122,6 +123,7 @@
> > + # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
> > + # endif
> > + #else
> > ++# define EXPAT_FMT_LLX(midpart) "%" midpart "llx"
> > + # define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
> > + # if ! defined(ULONG_MAX)
> > + # error Compiler did not define ULONG_MAX for us
> > +diff --git a/lib/xmlparse.c b/lib/xmlparse.c
> > +index 1bafb948..75a7e5d0 100644
> > +--- a/lib/xmlparse.c
> > ++++ b/lib/xmlparse.c
> > +@@ -604,7 +604,7 @@ static ELEMENT_TYPE *getElementType(XML_Parser
> parser, const ENCODING *enc,
> > +
> > + static XML_Char *copyString(const XML_Char *s, XML_Parser parser);
> > +
> > +-static unsigned long generate_hash_secret_salt(XML_Parser parser);
> > ++static struct sipkey generate_hash_secret_salt(void);
> > + static XML_Bool startParsing(XML_Parser parser);
> > +
> > + static XML_Parser parserCreate(const XML_Char *encodingName,
> > +@@ -777,7 +777,8 @@ struct XML_ParserStruct {
> > + XML_Bool m_useForeignDTD;
> > + enum XML_ParamEntityParsing m_paramEntityParsing;
> > + #endif
> > +- unsigned long m_hash_secret_salt;
> > ++ struct sipkey m_hash_secret_salt_128;
> > ++ XML_Bool m_hash_secret_salt_set;
> > + #if XML_GE == 1
> > + ACCOUNTING m_accounting;
> > + MALLOC_TRACKER m_alloc_tracker;
> > +@@ -1189,69 +1190,65 @@ gather_time_entropy(void) {
> > +
> > + #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && !
> defined(HAVE_ARC4RANDOM) */
> > +
> > +-static unsigned long
> > +-ENTROPY_DEBUG(const char *label, unsigned long entropy) {
> > ++static struct sipkey
> > ++ENTROPY_DEBUG(const char *label, struct sipkey entropy_128) {
> > + if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
> > +- fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
> > +- (int)sizeof(entropy) * 2, entropy, (unsigned
> > long)sizeof(entropy));
> > ++ fprintf(stderr,
> > ++ "expat: Entropy: %s --> [0x" EXPAT_FMT_LLX(
> > ++ "016") ", 0x" EXPAT_FMT_LLX("016") "] (16 bytes)\n",
> > ++ label, (unsigned long long)entropy_128.k[0],
> > ++ (unsigned long long)entropy_128.k[1]);
> > + }
> > +- return entropy;
> > ++ return entropy_128;
> > + }
> > +
> > +-static unsigned long
> > +-generate_hash_secret_salt(XML_Parser parser) {
> > +- unsigned long entropy;
> > +- (void)parser;
> > ++static struct sipkey
> > ++generate_hash_secret_salt(void) {
> > ++ struct sipkey entropy;
> > +
> > + /* "Failproof" high quality providers: */
> > + #if defined(HAVE_ARC4RANDOM_BUF)
> > + arc4random_buf(&entropy, sizeof(entropy));
> > + return ENTROPY_DEBUG("arc4random_buf", entropy);
> > + #elif defined(HAVE_ARC4RANDOM)
> > +- writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
> > ++ writeRandomBytes_arc4random(&entropy, sizeof(entropy));
> > + return ENTROPY_DEBUG("arc4random", entropy);
> > + #else
> > + /* Try high quality providers first .. */
> > + # ifdef _WIN32
> > +- if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
> > ++ if (writeRandomBytes_rand_s(&entropy, sizeof(entropy))) {
> > + return ENTROPY_DEBUG("rand_s", entropy);
> > + }
> > + # elif defined(HAVE_GETRANDOM) ||
> defined(HAVE_SYSCALL_GETRANDOM)
> > +- if (writeRandomBytes_getrandom_nonblock((void *)&entropy,
> > sizeof(entropy))) {
> > ++ if (writeRandomBytes_getrandom_nonblock(&entropy, sizeof(entropy))) {
> > + return ENTROPY_DEBUG("getrandom", entropy);
> > + }
> > + # endif
> > + # if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
> > +- if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
> > ++ if (writeRandomBytes_dev_urandom(&entropy, sizeof(entropy))) {
> > + return ENTROPY_DEBUG("/dev/urandom", entropy);
> > + }
> > + # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
> > + /* .. and self-made low quality for backup: */
> > +
> > +- entropy = gather_time_entropy();
> > ++ entropy.k[0] = 0;
> > ++ entropy.k[1] = gather_time_entropy();
> > + # if ! defined(__wasi__)
> > + /* Process ID is 0 bits entropy if attacker has local access */
> > +- entropy ^= getpid();
> > ++ entropy.k[1] ^= getpid();
> > + # endif
> > +
> > + /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
> > + if (sizeof(unsigned long) == 4) {
> > +- return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
> > ++ entropy.k[1] *= 2147483647;
> > ++ return ENTROPY_DEBUG("fallback(4)", entropy);
> > + } else {
> > +- return ENTROPY_DEBUG("fallback(8)",
> > +- entropy * (unsigned long)2305843009213693951ULL);
> > ++ entropy.k[1] *= 2305843009213693951ULL;
> > ++ return ENTROPY_DEBUG("fallback(8)", entropy);
> > + }
> > + #endif
> > + }
> > +
> > +-static unsigned long
> > +-get_hash_secret_salt(XML_Parser parser) {
> > +- const XML_Parser rootParser = getRootParserOf(parser, NULL);
> > +- assert(! rootParser->m_parentParser);
> > +-
> > +- return rootParser->m_hash_secret_salt;
> > +-}
> > +-
> > + static enum XML_Error
> > + callProcessor(XML_Parser parser, const char *start, const char *end,
> > + const char **endPtr) {
> > +@@ -1320,8 +1316,10 @@ callProcessor(XML_Parser parser, const char *start,
> const char *end,
> > + static XML_Bool /* only valid for root parser */
> > + startParsing(XML_Parser parser) {
> > + /* hash functions must be initialized before setContext() is called */
> > +- if (parser->m_hash_secret_salt == 0)
> > +- parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
> > ++ if (parser->m_hash_secret_salt_set != XML_TRUE) {
> > ++ parser->m_hash_secret_salt_128 = generate_hash_secret_salt();
> > ++ parser->m_hash_secret_salt_set = XML_TRUE;
> > ++ }
> > + if (parser->m_ns) {
> > + /* implicit context only set for root parser, since child
> > + parsers (i.e. external entity parsers) will inherit it
> > +@@ -1609,7 +1607,9 @@ parserInit(XML_Parser parser, const XML_Char
> *encodingName) {
> > + parser->m_useForeignDTD = XML_FALSE;
> > + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
> > + #endif
> > +- parser->m_hash_secret_salt = 0;
> > ++ parser->m_hash_secret_salt_128.k[0] = 0;
> > ++ parser->m_hash_secret_salt_128.k[1] = 0;
> > ++ parser->m_hash_secret_salt_set = XML_FALSE;
> > +
> > + #if XML_GE == 1
> > + memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
> > +@@ -1776,7 +1776,8 @@ XML_ExternalEntityParserCreate(XML_Parser
> oldParser, const XML_Char *context,
> > + from hash tables associated with either parser without us having
> > + to worry which hash secrets each table has.
> > + */
> > +- unsigned long oldhash_secret_salt;
> > ++ struct sipkey oldhash_secret_salt_128;
> > ++ XML_Bool oldhash_secret_salt_set;
> > + XML_Bool oldReparseDeferralEnabled;
> > +
> > + /* Validate the oldParser parameter before we pull everything out of it
> > */
> > +@@ -1822,7 +1823,8 @@ XML_ExternalEntityParserCreate(XML_Parser
> oldParser, const XML_Char *context,
> > + from hash tables associated with either parser without us having
> > + to worry which hash secrets each table has.
> > + */
> > +- oldhash_secret_salt = parser->m_hash_secret_salt;
> > ++ oldhash_secret_salt_128 = parser->m_hash_secret_salt_128;
> > ++ oldhash_secret_salt_set = parser->m_hash_secret_salt_set;
> > + oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled;
> > +
> > + #ifdef XML_DTD
> > +@@ -1877,7 +1879,8 @@ XML_ExternalEntityParserCreate(XML_Parser
> oldParser, const XML_Char *context,
> > + parser->m_externalEntityRefHandlerArg =
> > oldExternalEntityRefHandlerArg;
> > + parser->m_defaultExpandInternalEntities =
> > oldDefaultExpandInternalEntities;
> > + parser->m_ns_triplets = oldns_triplets;
> > +- parser->m_hash_secret_salt = oldhash_secret_salt;
> > ++ parser->m_hash_secret_salt_128 = oldhash_secret_salt_128;
> > ++ parser->m_hash_secret_salt_set = oldhash_secret_salt_set;
> > + parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled;
> > + parser->m_parentParser = oldParser;
> > + #ifdef XML_DTD
> > +@@ -2321,6 +2324,7 @@ XML_SetParamEntityParsing(XML_Parser parser,
> > + #endif
> > + }
> > +
> > ++// DEPRECATED since Expat 2.7.6.
> > + int XMLCALL
> > + XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
> > + if (parser == NULL)
> > +@@ -2332,10 +2336,46 @@ XML_SetHashSalt(XML_Parser parser, unsigned
> long hash_salt) {
> > + /* block after XML_Parse()/XML_ParseBuffer() has been called */
> > + if (parserBusy(rootParser))
> > + return 0;
> > +- rootParser->m_hash_secret_salt = hash_salt;
> > ++
> > ++ rootParser->m_hash_secret_salt_128.k[0] = 0;
> > ++ rootParser->m_hash_secret_salt_128.k[1] = hash_salt;
> > ++
> > ++ if (hash_salt != 0) { // to remain backwards compatible
> > ++ rootParser->m_hash_secret_salt_set = XML_TRUE;
> > ++
> > ++ if (sizeof(unsigned long) == 4)
> > ++ ENTROPY_DEBUG("explicit(4)", rootParser->m_hash_secret_salt_128);
> > ++ else
> > ++ ENTROPY_DEBUG("explicit(8)", rootParser->m_hash_secret_salt_128);
> > ++ }
> > ++
> > + return 1;
> > + }
> > +
> > ++XML_Bool XMLCALL
> > ++XML_SetHashSalt16Bytes(XML_Parser parser, const uint8_t entropy[16]) {
> > ++ if (parser == NULL)
> > ++ return XML_FALSE;
> > ++
> > ++ if (entropy == NULL)
> > ++ return XML_FALSE;
> > ++
> > ++ const XML_Parser rootParser = getRootParserOf(parser, NULL);
> > ++ assert(! rootParser->m_parentParser);
> > ++
> > ++ /* block after XML_Parse()/XML_ParseBuffer() has been called */
> > ++ if (parserBusy(rootParser))
> > ++ return XML_FALSE;
> > ++
> > ++ sip_tokey(&(rootParser->m_hash_secret_salt_128), entropy);
> > ++
> > ++ rootParser->m_hash_secret_salt_set = XML_TRUE;
> > ++
> > ++ ENTROPY_DEBUG("explicit(16)", rootParser->m_hash_secret_salt_128);
> > ++
> > ++ return XML_TRUE;
> > ++}
> > ++
> > + enum XML_Status XMLCALL
> > + XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
> > + if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
> > +@@ -7837,8 +7877,10 @@ keylen(KEY s) {
> > +
> > + static void
> > + copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
> > +- key->k[0] = 0;
> > +- key->k[1] = get_hash_secret_salt(parser);
> > ++ const XML_Parser rootParser = getRootParserOf(parser, NULL);
> > ++ assert(! rootParser->m_parentParser);
> > ++
> > ++ *key = rootParser->m_hash_secret_salt_128;
> > + }
> > +
> > + static unsigned long FASTCALL
> > +diff --git a/tests/basic_tests.c b/tests/basic_tests.c
> > +index 023d9ce4..380caf19 100644
> > +--- a/tests/basic_tests.c
> > ++++ b/tests/basic_tests.c
> > +@@ -204,6 +204,30 @@ START_TEST(test_hash_collision) {
> > + END_TEST
> > + #undef COLLIDING_HASH_SALT
> > +
> > ++START_TEST(test_hash_salt_setter) {
> > ++ const uint8_t entropy[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
> > ++ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
> > ++ XML_Parser parser = XML_ParserCreate(NULL);
> > ++
> > ++ // NULL parser should be rejected
> > ++ assert_true(XML_SetHashSalt16Bytes(NULL, entropy) == XML_FALSE);
> > ++
> > ++ // NULL entropy should be rejected
> > ++ assert_true(XML_SetHashSalt16Bytes(parser, NULL) == XML_FALSE);
> > ++
> > ++ // Setting should be allowed more than once
> > ++ assert_true(XML_SetHashSalt16Bytes(parser, entropy) == XML_TRUE);
> > ++ assert_true(XML_SetHashSalt16Bytes(parser, entropy) == XML_TRUE);
> > ++
> > ++ // But not after parsing has started
> > ++ assert_true(XML_Parse(parser, "", 0, XML_FALSE /* isFinal */)
> > ++ == XML_STATUS_OK);
> > ++ assert_true(XML_SetHashSalt16Bytes(parser, entropy) == XML_FALSE);
> > ++
> > ++ XML_ParserFree(parser);
> > ++}
> > ++END_TEST
> > ++
> > + /* Regression test for SF bug #491986. */
> > + START_TEST(test_danish_latin1) {
> > + const char *text = "<?xml version='1.0' encoding='iso-8859-1'?>\n"
> > +@@ -6244,6 +6268,7 @@ make_basic_test_case(Suite *s) {
> > + tcase_add_test(tc_basic, test_bom_utf16_le);
> > + tcase_add_test(tc_basic, test_nobom_utf16_le);
> > + tcase_add_test(tc_basic, test_hash_collision);
> > ++ tcase_add_test(tc_basic, test_hash_salt_setter);
> > + tcase_add_test(tc_basic, test_illegal_utf8);
> > + tcase_add_test(tc_basic, test_utf8_auto_align);
> > + tcase_add_test(tc_basic, test_utf16);
> > diff --git a/meta/recipes-core/expat/expat_2.6.4.bb b/meta/recipes-
> core/expat/expat_2.6.4.bb
> > index 151720a9e3c..f5c3e3fdd2f 100644
> > --- a/meta/recipes-core/expat/expat_2.6.4.bb
> > +++ b/meta/recipes-core/expat/expat_2.6.4.bb
> > @@ -51,6 +51,9 @@ SRC_URI =
> "${GITHUB_BASE_URI}/download/R_${VERSION_TAG}/expat-${PV}.tar.bz2 \
> > file://CVE-2026-32777-02.patch \
> > file://CVE-2026-32778-01.patch \
> > file://CVE-2026-32778-02.patch \
> > + file://CVE-2026-41080-01.patch \
> > + file://CVE-2026-41080-02.patch \
> > + file://CVE-2026-41080-03.patch \
> > "
> >
> > GITHUB_BASE_URI = "https://github.com/libexpat/libexpat/releases/"
>
>
> --
> Yoann Congal
> Smile ECS
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#236695):
https://lists.openembedded.org/g/openembedded-core/message/236695
Mute This Topic: https://lists.openembedded.org/mt/119168855/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-