On Fri, 2024-03-29 at 05:02 +0000, Meenali Gupta via
lists.openembedded.org wrote:
> +2.40.0
> diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0010.patch
> b/meta/recipes-core/expat/expat/CVE-2023-52425-0010.patch
> new file mode 100644
> index 0000000000..8ca364e4eb
> --- /dev/null
> +++ b/meta/recipes-core/expat/expat/CVE-2023-52425-0010.patch
> @@ -0,0 +1,110 @@
> +From 60b74209899a67d426d208662674b55a5eed918c Mon Sep 17 00:00:00
> 2001
> +From: Snild Dolkow <sn...@sony.com>
> +Date: Wed, 4 Oct 2023 16:00:14 +0200
> +Subject: [PATCH] Bypass partial token heuristic when close to
> maximum buffer
> + size
> +
> +For huge tokens, we may end up in a situation where the partial
> token
> +parse deferral heuristic demands more bytes than Expat's maximum
> buffer
> +size (currently ~half of INT_MAX) could fit.
> +
> +INT_MAX/2 is 1024 MiB on most systems. Clearly, a token of 950 MiB
> could
> +fit in that buffer, but the reparse threshold might be such that
> +callProcessor() will defer it, allowing the app to keep filling the
> +buffer until XML_GetBuffer() eventually returns a memory error.
> +
> +By bypassing the heuristic when we're getting close to the maximum
> +buffer size, it will once again be possible to parse tokens in the
> size
> +range INT_MAX/2/ratio < size < INT_MAX/2 reliably.
> +
> +We subtract the last buffer fill size as a way to detect that the
> next
> +XML_GetBuffer() call has a risk of returning a memory error --
> assuming
> +that the application is likely to keep using the same (or smaller)
> fill.
> +
> +We subtract XML_CONTEXT_BYTES because that's the maximum amount of
> bytes
> +that could remain at the start of the buffer, preceding the partial
> +token. Technically, it could be fewer bytes, but XML_CONTEXT_BYTES
> is
> +normally small relative to INT_MAX, and is much simpler to use.
> +
> +Co-authored-by: Sebastian Pipping <sebast...@pipping.org>
> +
> +CVE: CVE-2023-52425
> +
> +Upstream-Status: Backport
> [https://github.com/libexpat/libexpat/commit/60b74209899a67d426d20866
> 2674b55a5eed918c]
> +
> +Signed-off-by: Meenali Gupta <meenali.gu...@windriver.com>
> +---
> + lib/xmlparse.c | 23 ++++++++++++++++++++++-
> + 1 file changed, 22 insertions(+), 1 deletion(-)
> +
> +diff --git a/lib/xmlparse.c b/lib/xmlparse.c
> +index 6746d70..32c57f6 100644
> +--- a/lib/xmlparse.c
> ++++ b/lib/xmlparse.c
> +@@ -205,6 +205,8 @@ typedef char ICHAR;
> + /* Do safe (NULL-aware) pointer arithmetic */
> + #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
> +
> ++#define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b))
> ++
> + #include "internal.h"
> + #include "xmltok.h"
> + #include "xmlrole.h"
> +@@ -634,6 +636,7 @@ struct XML_ParserStruct {
> +   const char *m_parseEndPtr;
> +   size_t m_partialTokenBytesBefore; /* used in heuristic to avoid
> O(n^2) */
> +   XML_Bool m_reparseDeferralEnabled;
> ++  int m_lastBufferRequestSize;
> +   XML_Char *m_dataBuf;
> +   XML_Char *m_dataBufEnd;
> +   XML_StartElementHandler m_startElementHandler;
> +@@ -975,7 +978,18 @@ callProcessor(XML_Parser parser, const char
> *start, const char *end,
> +     // Heuristic: don't try to parse a partial token again until
> the amount of
> +     // available data has increased significantly.
> +     const size_t had_before = parser->m_partialTokenBytesBefore;
> +-    const bool enough = (have_now >= 2 * had_before);
> ++    // ...but *do* try anyway if we're close to reaching the max
> buffer size.
> ++    size_t close_to_maxbuf = INT_MAX / 2 + (INT_MAX & 1); // round
> up
> ++#if XML_CONTEXT_BYTES > 0
> ++    // subtract XML_CONTEXT_BYTES, but don't go below zero
> ++    close_to_maxbuf -= EXPAT_MIN(close_to_maxbuf,
> XML_CONTEXT_BYTES);
> ++#endif
> ++    // subtract the last buffer fill size, but don't go below zero
> ++    // m_lastBufferRequestSize is never assigned a value < 0, so
> the cast is ok
> ++    close_to_maxbuf
> ++        -= EXPAT_MIN(close_to_maxbuf, (size_t)parser-
> >m_lastBufferRequestSize);
> ++    const bool enough
> ++        = (have_now >= 2 * had_before) || (have_now >
> close_to_maxbuf);
> +
> +     if (! enough) {
> +       *endPtr = start; // callers may expect this to be set
> +@@ -1177,6 +1191,7 @@ parserInit(XML_Parser parser, const XML_Char
> *encodingName) {
> +   parser->m_parseEndPtr = NULL;
> +   parser->m_partialTokenBytesBefore = 0;
> +   parser->m_reparseDeferralEnabled =
> g_reparseDeferralEnabledDefault;
> ++  parser->m_lastBufferRequestSize = 0;
> +   parser->m_declElementType = NULL;
> +   parser->m_declAttributeId = NULL;
> +   parser->m_declEntity = NULL;
> +@@ -1911,6 +1926,9 @@ XML_Parse(XML_Parser parser, const char *s,
> int len, int isFinal) {
> +       parser->m_processor = errorProcessor;
> +       return XML_STATUS_ERROR;
> +     }
> ++    // though this isn't a buffer request, we assume that `len` is
> the app's
> ++    // preferred buffer fill size, and therefore save it here.
> ++    parser->m_lastBufferRequestSize = len;
> +     parser->m_parseEndByteIndex += len;
> +     parser->m_positionPtr = s;
> +     parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;]

You seem to have dropped a hunk to this specific patch here and removed
test files from others but have not documented any of this in commit
message. This patch, for example, needs at least this:

https://github.com/libexpat/libexpat/pull/771/commits/119ae277abaabd4d17b2e64300fec712ef403b28

I didn't see it included.

Please also note this in release notes:

Backporters should be careful to no omit parts of
pull request #789 and to include earlier pull request #771,
in order to not break the fix.

Thanks,

Anuj
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#197626): 
https://lists.openembedded.org/g/openembedded-core/message/197626
Mute This Topic: https://lists.openembedded.org/mt/105211620/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to