From patchwork Tue Apr 16 12:06:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 42535 X-Patchwork-Delegate: steve@sakoman.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 968A9C0650F for ; Tue, 16 Apr 2024 12:07:21 +0000 (UTC) Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by mx.groups.io with SMTP id smtpd.web10.19027.1713269237383670149 for ; Tue, 16 Apr 2024 05:07:17 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20230601.gappssmtp.com header.s=20230601 header.b=0/okqW2Q; spf=softfail (domain: sakoman.com, ip: 209.85.210.181, mailfrom: steve@sakoman.com) Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-6f00f24f761so1425882b3a.3 for ; Tue, 16 Apr 2024 05:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20230601.gappssmtp.com; s=20230601; t=1713269237; x=1713874037; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=JMXW6akkv8dJnTw7gFywhh6xlPyp1/bSxvZU5McLwok=; b=0/okqW2QlzyEGbS3wDQzCXw9CDBjxFBnCKQove4eVE7q+nrp7VRjR+Y1XqG2zRMrdR J7ArmjEgvMESEnoq3SPKlwPiNJScIGdTJayq+DF2tKtt4vz+ESrZDm+4ZcMbYw/0DM/W 5JbLvcPGgIHNo7+OmbA5t1hWg/9+aHmsBNyw0FoRZbkvPSDLtbqIR4d/uw7BDN+CF4zU dTNQj3FHB2Iir+wUXECLe1eD4GA84jrMt8qQbJaWpDIh7Mzment4yNvSdsdDPetob/ck A+dHgpHON1f7rn6+W1ia3MsMeh8qGc2lI3lqrtkadkmk5q1yioOboGpvLKxdlvKUufpt +F5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713269237; x=1713874037; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JMXW6akkv8dJnTw7gFywhh6xlPyp1/bSxvZU5McLwok=; b=Cl/pkoTAiRsm9z/wJ0XKVGX34s6pYCI+Efa8CiBOPwVNksjxbo2P7V9EWnFhQ94K+Z NFG5keGzxucYu2DF6CQPurxA+iXCOq3PntH31r4OIVpqWn0vElbmJq1Xe5r4OYlSFdth AgOSmxaW2/UBhAEwiHwNEwKf+EW4aZnCXviaDitczw2bFXMCBlx7BSt+IjHRg/Oq0vaS RRU4MfymWM7C6w+JDQSFb/6VR0n1ryez70qYyBA6K/K3gFcVa6X9aiZPBT4ntfkrUxV+ +q7BkEUHBJr49SnPJvjkH0N9WYKe+uO6MVdrMnQ1KPIjnvGOBk1DIXHTASv/kb+K4jPo NTmQ== X-Gm-Message-State: AOJu0YyLuEg1TcZBde1DweSUOd8zY3CuxOB2HLe2htZ+aHjMSeuZ8LYP Uf2xTItNZV7wyd5Aylutka2u+yv1AqmraI3hend3VtegZpjK4teRL/ih1cs+S627yGoxseOtkdQ o6Jw= X-Google-Smtp-Source: AGHT+IGkxQcVu0L7z7tOZFKdmt9C7DDJGFQmJKQwE45HSFeMEQoKoY0s2hZ515wdkexab8M7lbkNQw== X-Received: by 2002:a05:6a00:acf:b0:6ec:ceb4:49b8 with SMTP id c15-20020a056a000acf00b006ecceb449b8mr14652055pfl.0.1713269235451; Tue, 16 Apr 2024 05:07:15 -0700 (PDT) Received: from xps13.. ([199.58.97.236]) by smtp.gmail.com with ESMTPSA id j5-20020aa78d05000000b006edd9339917sm8746111pfe.58.2024.04.16.05.07.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Apr 2024 05:07:15 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 07/10] Revert "expat: fix CVE-2023-52425" Date: Tue, 16 Apr 2024 05:06:54 -0700 Message-Id: <46fb46c0fff83da85f37a1ea705170a6d2039eff.1713268959.git.steve@sakoman.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 16 Apr 2024 12:07:21 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/198444 This reverts commit 1bdcd10930a2998f6bbe56b3ba4c9b6c91203b39. Causes ptest failures: {'expat': ['test_accounting_precision', 'test_return_ns_triplet', 'test_column_number_after_parse', 'test_default_current', 'test_external_entity_values']} Signed-off-by: Steve Sakoman --- .../expat/expat/CVE-2023-52425-0001.patch | 40 ---- .../expat/expat/CVE-2023-52425-0002.patch | 87 ------- .../expat/expat/CVE-2023-52425-0003.patch | 222 ------------------ .../expat/expat/CVE-2023-52425-0004.patch | 42 ---- .../expat/expat/CVE-2023-52425-0005.patch | 69 ------ .../expat/expat/CVE-2023-52425-0006.patch | 67 ------ .../expat/expat/CVE-2023-52425-0007.patch | 159 ------------- .../expat/expat/CVE-2023-52425-0008.patch | 95 -------- .../expat/expat/CVE-2023-52425-0009.patch | 52 ---- .../expat/expat/CVE-2023-52425-0010.patch | 111 --------- .../expat/expat/CVE-2023-52425-0011.patch | 89 ------- .../expat/expat/CVE-2023-52425-0012.patch | 87 ------- meta/recipes-core/expat/expat_2.5.0.bb | 12 - 13 files changed, 1132 deletions(-) delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0001.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0002.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0003.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0004.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0005.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0006.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0007.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0008.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0009.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0010.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0011.patch delete mode 100644 meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0001.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0001.patch deleted file mode 100644 index 4e21ade018..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0001.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d5b02e96ab95d2a7ae0aea72d00054b9d036d76d Mon Sep 17 00:00:00 2001 -From: Sebastian Pipping -Date: Thu, 9 Nov 2023 19:28:05 +0100 -Subject: [PATCH] xmlwf: Document argument "-q" - -Rebased-and-adapted-by: Snild Dolkow - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/d5b02e96ab95d2a7ae0aea72d00054b9d036d76d] - -Signed-off-by: Meenali Gupta ---- - doc/xmlwf.xml | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/doc/xmlwf.xml b/doc/xmlwf.xml -index 9603abf..3d35393 100644 ---- a/doc/xmlwf.xml -+++ b/doc/xmlwf.xml -@@ -313,6 +313,16 @@ supports both. - - - -+ -+ -+ -+ -+ Disable reparse deferral, and allow quadratic parse runtime -+ on large tokens (default: reparse deferral enabled). -+ -+ -+ -+ - - - --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0002.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0002.patch deleted file mode 100644 index 8376727778..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0002.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 09fdf998e7cf3f8f9327e6602077791095aedd4d Mon Sep 17 00:00:00 2001 -From: Sebastian Pipping -Date: Thu, 9 Nov 2023 19:14:14 +0100 -Subject: [PATCH] xmlwf: Support disabling reparse deferral - -Rebased-and-adapted-by: Snild Dolkow - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/09fdf998e7cf3f8f9327e6602077791095aedd4d] - -Signed-off-by: Meenali Gupta ---- - xmlwf/xmlwf.c | 20 ++++++++++++++++++++ - xmlwf/xmlwf_helpgen.py | 4 ++++ - 2 files changed, 24 insertions(+) - -diff --git a/xmlwf/xmlwf.c b/xmlwf/xmlwf.c -index dd023a9..9a5441c 100644 ---- a/xmlwf/xmlwf.c -+++ b/xmlwf/xmlwf.c -@@ -911,6 +911,9 @@ usage(const XML_Char *prog, int rc) { - T("billion laughs attack protection:\n") - T(" NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n") - T("\n") -+ T("reparse deferral:\n") -+ T(" -q disable reparse deferral, and allow [q]uadratic parse runtime with large tokens\n") -+ T("\n") - T(" -a FACTOR set maximum tolerated [a]mplification factor (default: 100.0)\n") - T(" -b BYTES set number of output [b]ytes needed to activate (default: 8 MiB)\n") - T("\n") -@@ -967,6 +970,8 @@ tmain(int argc, XML_Char **argv) { - unsigned long long attackThresholdBytes; - XML_Bool attackThresholdGiven = XML_FALSE; - -+ XML_Bool disableDeferral = XML_FALSE; -+ - int exitCode = XMLWF_EXIT_SUCCESS; - enum XML_ParamEntityParsing paramEntityParsing - = XML_PARAM_ENTITY_PARSING_NEVER; -@@ -1091,6 +1096,11 @@ tmain(int argc, XML_Char **argv) { - #endif - break; - } -+ case T('q'): { -+ disableDeferral = XML_TRUE; -+ j++; -+ break; -+ } - case T('\0'): - if (j > 1) { - i++; -@@ -1136,6 +1146,16 @@ tmain(int argc, XML_Char **argv) { - #endif - } - -+ if (disableDeferral) { -+ const XML_Bool success = XML_SetReparseDeferralEnabled(parser, XML_FALSE); -+ if (! success) { -+ // This prevents tperror(..) from reporting misleading "[..]: Success" -+ errno = EINVAL; -+ tperror(T("Failed to disable reparse deferral")); -+ exit(XMLWF_EXIT_INTERNAL_ERROR); -+ } -+ } -+ - if (requireStandalone) - XML_SetNotStandaloneHandler(parser, notStandalone); - XML_SetParamEntityParsing(parser, paramEntityParsing); -diff --git a/xmlwf/xmlwf_helpgen.py b/xmlwf/xmlwf_helpgen.py -index c2a527f..1bd0a0a 100755 ---- a/xmlwf/xmlwf_helpgen.py -+++ b/xmlwf/xmlwf_helpgen.py -@@ -81,6 +81,10 @@ billion_laughs.add_argument('-a', metavar='FACTOR', - help='set maximum tolerated [a]mplification factor (default: 100.0)') - billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB)') - -+reparse_deferral = parser.add_argument_group('reparse deferral') -+reparse_deferral.add_argument('-q', metavar='FACTOR', -+ help='disable reparse deferral, and allow [q]uadratic parse runtime with large tokens') -+ - parser.add_argument('files', metavar='FILE', nargs='*', help='file to process (default: STDIN)') - - info = parser.add_argument_group('info arguments') --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0003.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0003.patch deleted file mode 100644 index e5c3606e19..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0003.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 9cdf9b8d77d5c2c2a27d15fb68dd3f83cafb45a1 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Thu, 17 Aug 2023 16:25:26 +0200 -Subject: [PATCH] Skip parsing after repeated partials on the same token When - the parse buffer contains the starting bytes of a token but not all of them, - we cannot parse the token to completion. We call this a partial token. When - this happens, the parse position is reset to the start of the token, and the - parse() call returns. The client is then expected to provide more data and - call parse() again. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In extreme cases, this means that the bytes of a token may be parsed -many times: once for every buffer refill required before the full token -is present in the buffer. - -Math: - Assume there's a token of T bytes - Assume the client fills the buffer in chunks of X bytes - We'll try to parse X, 2X, 3X, 4X ... until mX == T (technically >=) - That's (m²+m)X/2 = (T²/X+T)/2 bytes parsed (arithmetic progression) - While it is alleviated by larger refills, this amounts to O(T²) - -Expat grows its internal buffer by doubling it when necessary, but has -no way to inform the client about how much space is available. Instead, -we add a heuristic that skips parsing when we've repeatedly stopped on -an incomplete token. Specifically: - - * Only try to parse if we have a certain amount of data buffered - * Every time we stop on an incomplete token, double the threshold - * As soon as any token completes, the threshold is reset - -This means that when we get stuck on an incomplete token, the threshold -grows exponentially, effectively making the client perform larger buffer -fills, limiting how many times we can end up re-parsing the same bytes. - -Math: - Assume there's a token of T bytes - Assume the client fills the buffer in chunks of X bytes - We'll try to parse X, 2X, 4X, 8X ... until (2^k)X == T (or larger) - That's (2^(k+1)-1)X bytes parsed -- e.g. 15X if T = 8X - This is equal to 2T-X, which amounts to O(T) - -We could've chosen a faster growth rate, e.g. 4 or 8. Those seem to -increase performance further, at the cost of further increasing the -risk of growing the buffer more than necessary. This can easily be -adjusted in the future, if desired. - -This is all completely transparent to the client, except for: -1. possible delay of some callbacks (when our heuristic overshoots) -2. apps that never do isFinal=XML_TRUE could miss data at the end - -For the affected testdata, this change shows a 100-400x speedup. -The recset.xml benchmark shows no clear change either way. - -Before: -benchmark -n ../testdata/largefiles/recset.xml 65535 3 - 3 loops, with buffer size 65535. Average time per loop: 0.270223 -benchmark -n ../testdata/largefiles/aaaaaa_attr.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 15.033048 -benchmark -n ../testdata/largefiles/aaaaaa_cdata.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.018027 -benchmark -n ../testdata/largefiles/aaaaaa_comment.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 11.775362 -benchmark -n ../testdata/largefiles/aaaaaa_tag.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 11.711414 -benchmark -n ../testdata/largefiles/aaaaaa_text.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.019362 - -After: -./run.sh benchmark -n ../testdata/largefiles/recset.xml 65535 3 - 3 loops, with buffer size 65535. Average time per loop: 0.269030 -./run.sh benchmark -n ../testdata/largefiles/aaaaaa_attr.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.044794 -./run.sh benchmark -n ../testdata/largefiles/aaaaaa_cdata.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.016377 -./run.sh benchmark -n ../testdata/largefiles/aaaaaa_comment.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.027022 -./run.sh benchmark -n ../testdata/largefiles/aaaaaa_tag.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.099360 -./run.sh benchmark -n ../testdata/largefiles/aaaaaa_text.xml 4096 3 - 3 loops, with buffer size 4096. Average time per loop: 0.017956 - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/9cdf9b8d77d5c2c2a27d15fb68dd3f83cafb45a1] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 58 +++++++++++++++++++++++++++++++++----------------- - 1 file changed, 39 insertions(+), 19 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index bbffcaa..5695417 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -81,6 +81,7 @@ - # endif - #endif - -+#include - #include - #include /* memset(), memcpy() */ - #include -@@ -629,6 +630,7 @@ struct XML_ParserStruct { - const char *m_bufferLim; - XML_Index m_parseEndByteIndex; - const char *m_parseEndPtr; -+ size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */ - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; -@@ -960,6 +962,32 @@ get_hash_secret_salt(XML_Parser parser) { - return parser->m_hash_secret_salt; - } - -+static enum XML_Error -+callProcessor(XML_Parser parser, const char *start, const char *end, -+ const char **endPtr) { -+ const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start); -+ -+ if (! parser->m_parsingStatus.finalBuffer) { -+ // 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); -+ -+ if (! enough) { -+ *endPtr = start; // callers may expect this to be set -+ return XML_ERROR_NONE; -+ } -+ } -+ const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); -+ // if we consumed nothing, remember what we had on this parse attempt. -+ if (*endPtr == start) { -+ parser->m_partialTokenBytesBefore = have_now; -+ } else { -+ parser->m_partialTokenBytesBefore = 0; -+ } -+ return ret; -+} -+ - static XML_Bool /* only valid for root parser */ - startParsing(XML_Parser parser) { - /* hash functions must be initialized before setContext() is called */ -@@ -1141,6 +1169,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) { - parser->m_bufferEnd = parser->m_buffer; - parser->m_parseEndByteIndex = 0; - parser->m_parseEndPtr = NULL; -+ parser->m_partialTokenBytesBefore = 0; - parser->m_declElementType = NULL; - parser->m_declAttributeId = NULL; - parser->m_declEntity = NULL; -@@ -1872,29 +1901,20 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { - to detect errors based on that fact. - */ - parser->m_errorCode -- = parser->m_processor(parser, parser->m_bufferPtr, -- parser->m_parseEndPtr, &parser->m_bufferPtr); -+ = callProcessor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, -+ &parser->m_bufferPtr); - - if (parser->m_errorCode == XML_ERROR_NONE) { - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: -- /* It is hard to be certain, but it seems that this case -- * cannot occur. This code is cleaning up a previous parse -- * with no new data (since len == 0). Changing the parsing -- * state requires getting to execute a handler function, and -- * there doesn't seem to be an opportunity for that while in -- * this circumstance. -- * -- * Given the uncertainty, we retain the code but exclude it -- * from coverage tests. -- * -- * LCOV_EXCL_START -- */ -+ /* While we added no new data, the finalBuffer flag may have caused -+ * us to parse previously-unparsed data in the internal buffer. -+ * If that triggered a callback to the application, it would have -+ * had an opportunity to suspend parsing. */ - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, - parser->m_bufferPtr, &parser->m_position); - parser->m_positionPtr = parser->m_bufferPtr; - return XML_STATUS_SUSPENDED; -- /* LCOV_EXCL_STOP */ - case XML_INITIALIZED: - case XML_PARSING: - parser->m_parsingStatus.parsing = XML_FINISHED; -@@ -1924,7 +1944,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { - parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - - parser->m_errorCode -- = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); -+ = callProcessor(parser, s, parser->m_parseEndPtr = s + len, &end); - - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; -@@ -2027,8 +2047,8 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { - parser->m_parseEndByteIndex += len; - parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - -- parser->m_errorCode = parser->m_processor( -- parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); -+ parser->m_errorCode = callProcessor(parser, start, parser->m_parseEndPtr, -+ &parser->m_bufferPtr); - - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; -@@ -2220,7 +2240,7 @@ XML_ResumeParser(XML_Parser parser) { - } - parser->m_parsingStatus.parsing = XML_PARSING; - -- parser->m_errorCode = parser->m_processor( -+ parser->m_errorCode = callProcessor( - parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); - - if (parser->m_errorCode != XML_ERROR_NONE) { --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0004.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0004.patch deleted file mode 100644 index 35e8e0b1e5..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0004.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b9d398517befeb944cbbadadf10992b07e96fa2 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Mon, 4 Sep 2023 17:21:14 +0200 -Subject: [PATCH] [PATCH] Don't update partial token heuristic on error - -Suggested-by: Sebastian Pipping - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/1b9d398517befeb944cbbadadf10992b07e96fa2] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 5695417..5c66f54 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -979,11 +979,13 @@ callProcessor(XML_Parser parser, const char *start, const char *end, - } - } - const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); -- // if we consumed nothing, remember what we had on this parse attempt. -- if (*endPtr == start) { -- parser->m_partialTokenBytesBefore = have_now; -- } else { -- parser->m_partialTokenBytesBefore = 0; -+ if (ret == XML_ERROR_NONE) { -+ // if we consumed nothing, remember what we had on this parse attempt. -+ if (*endPtr == start) { -+ parser->m_partialTokenBytesBefore = have_now; -+ } else { -+ parser->m_partialTokenBytesBefore = 0; -+ } - } - return ret; - } --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0005.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0005.patch deleted file mode 100644 index d4e112db58..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0005.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 09957b8ced725b96a95acff150facda93f03afe1 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Thu, 26 Oct 2023 10:41:00 +0200 -Subject: [PATCH] Allow XML_GetBuffer() with len=0 on a fresh parser - -len=0 was previously OK if there had previously been a non-zero call. -It makes sense to allow an application to work the same way on a -newly-created parser, and not have to care if its incoming buffer -happens to be 0. - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/09957b8ced725b96a95acff150facda93f03afe1] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 5c66f54..5b112c6 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -2095,7 +2095,8 @@ XML_GetBuffer(XML_Parser parser, int len) { - default:; - } - -- if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { -+ if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd) -+ || parser->m_buffer == NULL) { - #ifdef XML_CONTEXT_BYTES - int keep; - #endif /* defined XML_CONTEXT_BYTES */ -@@ -2118,8 +2119,9 @@ XML_GetBuffer(XML_Parser parser, int len) { - } - neededSize += keep; - #endif /* defined XML_CONTEXT_BYTES */ -- if (neededSize -- <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { -+ if (parser->m_buffer && parser->m_bufferPtr -+ && neededSize -+ <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { - #ifdef XML_CONTEXT_BYTES - if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { - int offset -@@ -2133,14 +2135,12 @@ XML_GetBuffer(XML_Parser parser, int len) { - parser->m_bufferPtr -= offset; - } - #else -- if (parser->m_buffer && parser->m_bufferPtr) { -- memmove(parser->m_buffer, parser->m_bufferPtr, -- EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); -- parser->m_bufferEnd -- = parser->m_buffer -- + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); -- parser->m_bufferPtr = parser->m_buffer; -- } -+ memmove(parser->m_buffer, parser->m_bufferPtr, -+ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); -+ parser->m_bufferEnd -+ = parser->m_buffer -+ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); -+ parser->m_bufferPtr = parser->m_buffer; - #endif /* not defined XML_CONTEXT_BYTES */ - } else { - char *newBuf; --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0006.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0006.patch deleted file mode 100644 index c1fb4893ed..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0006.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 9fe3672459c1bf10926b85f013aa1b623d855545 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Mon, 18 Sep 2023 20:32:55 +0200 -Subject: [PATCH] tests: Run both with and without partial token heuristic - -If we always run with the heuristic enabled, it may hide some bugs by -grouping up input into bigger parse attempts. - -CI-fighting-assistance-by: Sebastian Pipping - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/9fe3672459c1bf10926b85f013aa1b623d855545] - -Signed-off-by: Meenali Gupta ---- - lib/internal.h | 3 +++ - lib/xmlparse.c | 5 ++++- - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/lib/internal.h b/lib/internal.h -index 03c8fde..1df417f 100644 ---- a/lib/internal.h -+++ b/lib/internal.h -@@ -31,6 +31,7 @@ - Copyright (c) 2016-2022 Sebastian Pipping - Copyright (c) 2018 Yury Gribov - Copyright (c) 2019 David Loffredo -+ Copyright (c) 2023 Sony Corporation / Snild Dolkow - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining -@@ -160,6 +161,8 @@ unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); - const char *unsignedCharToPrintable(unsigned char c); - #endif - -+extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c -+ // - #ifdef __cplusplus - } - #endif -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 5b112c6..be6dd92 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -615,6 +615,8 @@ static unsigned long getDebugLevel(const char *variableName, - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) - -+XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c -+ // - struct XML_ParserStruct { - /* The first member must be m_userData so that the XML_GetUserData - macro works. */ -@@ -967,7 +969,8 @@ callProcessor(XML_Parser parser, const char *start, const char *end, - const char **endPtr) { - const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start); - -- if (! parser->m_parsingStatus.finalBuffer) { -+ if (g_reparseDeferralEnabledDefault -+ && ! parser->m_parsingStatus.finalBuffer) { - // 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; --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0007.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0007.patch deleted file mode 100644 index e2fb35eae6..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0007.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 1d3162da8a85a398ab451aadd6c2ad19587e5a68 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Mon, 11 Sep 2023 15:31:24 +0200 -Subject: [PATCH] Add app setting for enabling/disabling reparse heuristic - -Suggested-by: Sebastian Pipping -CI-fighting-assistance-by: Sebastian Pipping - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/1d3162da8a85a398ab451aadd6c2ad19587e5a68] - -Signed-off-by: Meenali Gupta ---- - doc/reference.html | 30 ++++++++++++++++++++++++------ - lib/expat.h | 5 +++++ - lib/libexpat.def.cmake | 2 ++ - lib/xmlparse.c | 13 ++++++++++++- - 4 files changed, 43 insertions(+), 7 deletions(-) - -diff --git a/doc/reference.html b/doc/reference.html -index 9953aa7..7dd9370 100644 ---- a/doc/reference.html -+++ b/doc/reference.html -@@ -151,10 +151,11 @@ interface.

- - -
  • -- Billion Laughs Attack Protection -+ Attack Protection - -
  • -
  • Miscellaneous Functions -@@ -2123,11 +2124,7 @@ parse position may be before the beginning of the buffer.

    - return NULL.

    - - --

    Billion Laughs Attack Protection

    -- --

    The functions in this section configure the built-in -- protection against various forms of -- billion laughs attacks.

    -+

    Attack Protection

    - -

    XML_SetBillionLaughsAttackProtectionMaximumAmplification

    -
    -@@ -2215,6 +2212,27 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
    -   

    - - -+

    XML_SetReparseDeferralEnabled

    -+
    -+/* Added in Expat 2.6.0. */
    -+XML_Bool XMLCALL
    -+XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
    -+
    -+
    -+

    -+ Large tokens may require many parse calls before enough data is available for Expat to parse it in full. -+ If Expat retried parsing the token on every parse call, parsing could take quadratic time. -+ To avoid this, Expat only retries once a significant amount of new data is available. -+ This function allows disabling this behavior. -+

    -+

    -+ The enabled argument should be XML_TRUE or XML_FALSE. -+

    -+

    -+ Returns XML_TRUE on success, and XML_FALSE on error. -+

    -+
    -+ -

    Miscellaneous functions

    - -

    The functions in this section either obtain state information from -diff --git a/lib/expat.h b/lib/expat.h -index 9e64174..73dda6d 100644 ---- a/lib/expat.h -+++ b/lib/expat.h -@@ -16,6 +16,7 @@ - Copyright (c) 2016 Thomas Beutlich - Copyright (c) 2017 Rhodri James - Copyright (c) 2022 Thijs Schreijer -+ Copyright (c) 2023 Sony Corporation / Snild Dolkow - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining -@@ -1054,6 +1055,10 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( - XML_Parser parser, unsigned long long activationThresholdBytes); - #endif - -+/* Added in Expat 2.6.0. */ -+XMLPARSEAPI(XML_Bool) -+XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); -+ - /* Expat follows the semantic versioning convention. - See http://semver.org. - */ -diff --git a/lib/libexpat.def.cmake b/lib/libexpat.def.cmake -index 61a4f00..10ee9cd 100644 ---- a/lib/libexpat.def.cmake -+++ b/lib/libexpat.def.cmake -@@ -77,3 +77,5 @@ EXPORTS - ; added with version 2.4.0 - @_EXPAT_COMMENT_DTD_OR_GE@ XML_SetBillionLaughsAttackProtectionActivationThreshold @69 - @_EXPAT_COMMENT_DTD_OR_GE@ XML_SetBillionLaughsAttackProtectionMaximumAmplification @70 -+; added with version 2.6.0 -+ XML_SetReparseDeferralEnabled @71 -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index be6dd92..8cf32e0 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -633,6 +633,7 @@ struct XML_ParserStruct { - XML_Index m_parseEndByteIndex; - const char *m_parseEndPtr; - size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */ -+ XML_Bool m_reparseDeferralEnabled; - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; -@@ -969,7 +970,7 @@ callProcessor(XML_Parser parser, const char *start, const char *end, - const char **endPtr) { - const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start); - -- if (g_reparseDeferralEnabledDefault -+ if (parser->m_reparseDeferralEnabled - && ! parser->m_parsingStatus.finalBuffer) { - // Heuristic: don't try to parse a partial token again until the amount of - // available data has increased significantly. -@@ -1175,6 +1176,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) { - parser->m_parseEndByteIndex = 0; - parser->m_parseEndPtr = NULL; - parser->m_partialTokenBytesBefore = 0; -+ parser->m_reparseDeferralEnabled = g_reparseDeferralEnabledDefault; - parser->m_declElementType = NULL; - parser->m_declAttributeId = NULL; - parser->m_declEntity = NULL; -@@ -2601,6 +2603,15 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( - } - #endif /* XML_GE == 1 */ - -+XML_Bool XMLCALL -+XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) { -+ if (parser != NULL && (enabled == XML_TRUE || enabled == XML_FALSE)) { -+ parser->m_reparseDeferralEnabled = enabled; -+ return XML_TRUE; -+ } -+ return XML_FALSE; -+} -+ - /* Initially tag->rawName always points into the parse buffer; - for those TAG instances opened while the current parse buffer was - processed, and not yet closed, we need to store tag->rawName in a more --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0008.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0008.patch deleted file mode 100644 index fa25fcd2db..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0008.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 8ddd8e86aa446d02eb8d398972d3b10d4cad908a Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Fri, 29 Sep 2023 10:14:59 +0200 -Subject: [PATCH] Try to parse even when incoming len is zero - -If the reparse deferral setting has changed, it may be possible to -finish a token. - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/8ddd8e86aa446d02eb8d398972d3b10d4cad908a] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 55 ++++++++------------------------------------------ - 1 file changed, 8 insertions(+), 47 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 8cf32e0..f4ff66e 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -1896,46 +1896,8 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { - parser->m_parsingStatus.parsing = XML_PARSING; - } - -- if (len == 0) { -- parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; -- if (! isFinal) -- return XML_STATUS_OK; -- parser->m_positionPtr = parser->m_bufferPtr; -- parser->m_parseEndPtr = parser->m_bufferEnd; -- -- /* If data are left over from last buffer, and we now know that these -- data are the final chunk of input, then we have to check them again -- to detect errors based on that fact. -- */ -- parser->m_errorCode -- = callProcessor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, -- &parser->m_bufferPtr); -- -- if (parser->m_errorCode == XML_ERROR_NONE) { -- switch (parser->m_parsingStatus.parsing) { -- case XML_SUSPENDED: -- /* While we added no new data, the finalBuffer flag may have caused -- * us to parse previously-unparsed data in the internal buffer. -- * If that triggered a callback to the application, it would have -- * had an opportunity to suspend parsing. */ -- XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, -- parser->m_bufferPtr, &parser->m_position); -- parser->m_positionPtr = parser->m_bufferPtr; -- return XML_STATUS_SUSPENDED; -- case XML_INITIALIZED: -- case XML_PARSING: -- parser->m_parsingStatus.parsing = XML_FINISHED; -- /* fall through */ -- default: -- return XML_STATUS_OK; -- } -- } -- parser->m_eventEndPtr = parser->m_eventPtr; -- parser->m_processor = errorProcessor; -- return XML_STATUS_ERROR; -- } - #ifndef XML_CONTEXT_BYTES -- else if (parser->m_bufferPtr == parser->m_bufferEnd) { -+ if (parser->m_bufferPtr == parser->m_bufferEnd) { - const char *end; - int nLeftOver; - enum XML_Status result; -@@ -2006,15 +1968,14 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { - return result; - } - #endif /* not defined XML_CONTEXT_BYTES */ -- else { -- void *buff = XML_GetBuffer(parser, len); -- if (buff == NULL) -- return XML_STATUS_ERROR; -- else { -- memcpy(buff, s, len); -- return XML_ParseBuffer(parser, len, isFinal); -- } -+ void *buff = XML_GetBuffer(parser, len); -+ if (buff == NULL) -+ return XML_STATUS_ERROR; -+ if (len > 0) { -+ assert(s != NULL); // make sure s==NULL && len!=0 was rejected above -+ memcpy(buff, s, len); - } -+ return XML_ParseBuffer(parser, len, isFinal); - } - - enum XML_Status XMLCALL --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0009.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0009.patch deleted file mode 100644 index 9c1157faac..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0009.patch +++ /dev/null @@ -1,52 +0,0 @@ -From ad9c01be8ee5d3d5cac2bfd3949ad764541d35e7 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Thu, 26 Oct 2023 13:55:02 +0200 -Subject: [PATCH] Make external entity parser inherit partial token heuristic - setting - -The test is essentially a copy of the existing test for the setter, -adapted to run on the external parser instead of the original one. - -Suggested-by: Sebastian Pipping -CI-fighting-assistance-by: Sebastian Pipping - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/ad9c01be8ee5d3d5cac2bfd3949ad764541d35e7] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index f4ff66e..6746d70 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -1346,6 +1346,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, - to worry which hash secrets each table has. - */ - unsigned long oldhash_secret_salt; -+ XML_Bool oldReparseDeferralEnabled; - - /* Validate the oldParser parameter before we pull everything out of it */ - if (oldParser == NULL) -@@ -1390,6 +1391,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, - to worry which hash secrets each table has. - */ - oldhash_secret_salt = parser->m_hash_secret_salt; -+ oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled; - - #ifdef XML_DTD - if (! context) -@@ -1442,6 +1444,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, - parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - parser->m_ns_triplets = oldns_triplets; - parser->m_hash_secret_salt = oldhash_secret_salt; -+ parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled; - parser->m_parentParser = oldParser; - #ifdef XML_DTD - parser->m_paramEntityParsing = oldParamEntityParsing; --- -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 deleted file mode 100644 index 3fbf69de08..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0010.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 60b74209899a67d426d208662674b55a5eed918c Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -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 - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/60b74209899a67d426d208662674b55a5eed918c] - -Signed-off-by: Meenali Gupta ---- - 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; -@@ -2064,6 +2082,9 @@ XML_GetBuffer(XML_Parser parser, int len) { - default:; - } - -+ // whether or not the request succeeds, `len` seems to be the app's preferred -+ // buffer fill size; remember it. -+ parser->m_lastBufferRequestSize = len; - if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd) - || parser->m_buffer == NULL) { - #ifdef XML_CONTEXT_BYTES --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0011.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0011.patch deleted file mode 100644 index 800aaff544..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0011.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 3d8141d26a3b01ff948e00956cb0723a89dadf7f Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Mon, 20 Nov 2023 16:11:24 +0100 -Subject: [PATCH] Bypass partial token heuristic when nearing full buffer - -...instead of only when approaching the maximum buffer size INT/2+1. - -We'd like to give applications a chance to finish parsing a large token -before buffer reallocation, in case the reallocation fails. - -By bypassing the reparse deferral heuristic when getting close to the -filling the buffer, we give them this chance -- if the whole token is -present in the buffer, it will be parsed at that time. - -This may come at the cost of some extra reparse attempts. For a token -of n bytes, these extra parses cause us to scan over a maximum of -2n bytes (... + n/8 + n/4 + n/2 + n). Therefore, parsing of big tokens -remains O(n) in regard how many bytes we scan in attempts to parse. The -cost in reality is lower than that, since the reparses that happen due -to the bypass will affect m_partialTokenBytesBefore, delaying the next -ratio-based reparse. Furthermore, only the first token that "breaks -through" a buffer ceiling takes that extra reparse attempt; subsequent -large tokens will only bypass the heuristic if they manage to hit the -new buffer ceiling. - -Note that this cost analysis depends on the assumption that Expat grows -its buffer by doubling it (or, more generally, grows it exponentially). -If this changes, the cost of this bypass may increase. Hopefully, this -would be caught by test_big_tokens_take_linear_time or the new test. - -The bypass logic assumes that the application uses a consistent fill. -If the app increases its fill size, it may miss the bypass (and the -normal heuristic will apply). If the app decreases its fill size, the -bypass may be hit multiple times for the same buffer size. The very -worst case would be to always fill half of the remaining buffer space, -in which case parsing of a large n-byte token becomes O(n log n). - -As an added bonus, the new test case should be faster than the old one, -since it doesn't have to go all the way to 1GiB to check the behavior. - -Finally, this change necessitated a small modification to two existing -tests related to reparse deferral. These tests are testing the deferral -enabled setting, and assume that reparsing will not happen for any other -reason. By pre-growing the buffer, we make sure that this new deferral -does not affect those test cases. - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/3d8141d26a3b01ff948e00956cb0723a89dadf7f] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 32c57f6..2830c1e 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -978,18 +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; -- // ...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 -+ // ...but *do* try anyway if we're close to causing a reallocation. -+ size_t available_buffer -+ = EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); - #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); -+ available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES); - #endif -- // subtract the last buffer fill size, but don't go below zero -+ available_buffer -+ += EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd); - // 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); -+ = (have_now >= 2 * had_before) -+ || ((size_t)parser->m_lastBufferRequestSize > available_buffer); - - if (! enough) { - *endPtr = start; // callers may expect this to be set --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch deleted file mode 100644 index 8693e9449e..0000000000 --- a/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 119ae277abaabd4d17b2e64300fec712ef403b28 Mon Sep 17 00:00:00 2001 -From: Snild Dolkow -Date: Thu, 28 Sep 2023 18:26:19 +0200 -Subject: [PATCH] Grow buffer based on current size Until now, the buffer size - to grow to has been calculated based on the distance from the current parse - position to the end of the buffer. This means that the size of any - already-parsed data was not considered, leading to inconsistent buffer - growth. - -There was also a special case in XML_Parse() when XML_CONTEXT_BYTES was -zero, where the buffer size would be set to twice the incoming string -length. This patch replaces this with an XML_GetBuffer() call. - -Growing the buffer based on its total size makes its growth consistent. - -The commit includes a test that checks that we can reach the max buffer -size (usually INT_MAX/2 + 1) regardless of previously parsed content. - -GitHub CI couldn't allocate the full 1GiB with MinGW/wine32, though it -works locally with the same compiler and wine version. As a workaround, -the test tries to malloc 1GiB, and reduces `maxbuf` to 512MiB in case -of failure. - -CVE: CVE-2023-52425 - -Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/119ae277abaabd4d17b2e64300fec712ef403b28] - -Signed-off-by: Meenali Gupta ---- - lib/xmlparse.c | 33 ++++++++++++++++----------------- - 1 file changed, 16 insertions(+), 17 deletions(-) - -diff --git a/lib/xmlparse.c b/lib/xmlparse.c -index 2830c1e..81f9bb3 100644 ---- a/lib/xmlparse.c -+++ b/lib/xmlparse.c -@@ -1961,23 +1961,22 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { - &parser->m_position); - nLeftOver = s + len - end; - if (nLeftOver) { -- if (parser->m_buffer == NULL -- || nLeftOver > parser->m_bufferLim - parser->m_buffer) { -- /* avoid _signed_ integer overflow */ -- char *temp = NULL; -- const int bytesToAllocate = (int)((unsigned)len * 2U); -- if (bytesToAllocate > 0) { -- temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); -- } -- if (temp == NULL) { -- parser->m_errorCode = XML_ERROR_NO_MEMORY; -- parser->m_eventPtr = parser->m_eventEndPtr = NULL; -- parser->m_processor = errorProcessor; -- return XML_STATUS_ERROR; -- } -- parser->m_buffer = temp; -- parser->m_bufferLim = parser->m_buffer + bytesToAllocate; -+ // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED -+ // (and XML_ERROR_FINISHED) from XML_GetBuffer. -+ const enum XML_Parsing originalStatus = parser->m_parsingStatus.parsing; -+ parser->m_parsingStatus.parsing = XML_PARSING; -+ void *const temp = XML_GetBuffer(parser, nLeftOver); -+ parser->m_parsingStatus.parsing = originalStatus; -+ if (temp == NULL) { -+ // NOTE: parser->m_errorCode has already been set by XML_GetBuffer(). -+ parser->m_eventPtr = parser->m_eventEndPtr = NULL; -+ parser->m_processor = errorProcessor; -+ return XML_STATUS_ERROR; - } -+ // Since we know that the buffer was empty and XML_CONTEXT_BYTES is 0, we -+ // don't have any data to preserve, and can copy straight into the start -+ // of the buffer rather than the GetBuffer return pointer (which may be -+ // pointing further into the allocated buffer). - memcpy(parser->m_buffer, end, nLeftOver); - } - parser->m_bufferPtr = parser->m_buffer; -@@ -2135,7 +2134,7 @@ XML_GetBuffer(XML_Parser parser, int len) { - } else { - char *newBuf; - int bufferSize -- = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); -+ = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer); - if (bufferSize == 0) - bufferSize = INIT_BUFFER_SIZE; - do { --- -2.40.0 - diff --git a/meta/recipes-core/expat/expat_2.5.0.bb b/meta/recipes-core/expat/expat_2.5.0.bb index b7b5cce925..31e989cfe2 100644 --- a/meta/recipes-core/expat/expat_2.5.0.bb +++ b/meta/recipes-core/expat/expat_2.5.0.bb @@ -22,18 +22,6 @@ SRC_URI = "https://github.com/libexpat/libexpat/releases/download/R_${VERSION_TA file://CVE-2023-52426-009.patch \ file://CVE-2023-52426-010.patch \ file://CVE-2023-52426-011.patch \ - file://CVE-2023-52425-0001.patch \ - file://CVE-2023-52425-0002.patch \ - file://CVE-2023-52425-0003.patch \ - file://CVE-2023-52425-0004.patch \ - file://CVE-2023-52425-0005.patch \ - file://CVE-2023-52425-0006.patch \ - file://CVE-2023-52425-0007.patch \ - file://CVE-2023-52425-0008.patch \ - file://CVE-2023-52425-0009.patch \ - file://CVE-2023-52425-0010.patch \ - file://CVE-2023-52425-0011.patch \ - file://CVE-2023-52425-0012.patch \ " UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/"