summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch')
-rw-r--r--meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch87
1 files changed, 87 insertions, 0 deletions
diff --git a/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch b/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch
new file mode 100644
index 0000000000..8693e9449e
--- /dev/null
+++ b/meta/recipes-core/expat/expat/CVE-2023-52425-0012.patch
@@ -0,0 +1,87 @@
+From 119ae277abaabd4d17b2e64300fec712ef403b28 Mon Sep 17 00:00:00 2001
+From: Snild Dolkow <snild@sony.com>
+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 <meenali.gupta@windriver.com>
+---
+ 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
+