diff --git a/SOURCES/expat-CVE-2023-52425.patch b/SOURCES/expat-CVE-2023-52425.patch deleted file mode 100644 index bdd06ca..0000000 --- a/SOURCES/expat-CVE-2023-52425.patch +++ /dev/null @@ -1,375 +0,0 @@ -# erAck: backport of expat CVE-2023-52425 DoS fix -# https://github.com/libexpat/libexpat/commit/34b598c5f594b015c513c73f06e7ced3323edbf1 -# ---- firefox-115.9.0/parser/expat/lib/expat.h.expat-CVE-2023-52425 2024-03-11 20:36:11.000000000 +0100 -+++ firefox-115.9.0/parser/expat/lib/expat.h 2024-03-13 20:46:45.648505015 +0100 -@@ -1045,6 +1045,10 @@ XMLPARSEAPI(const XML_Feature *) - XML_GetFeatureList(void); - - -+/* 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. - */ ---- firefox-115.9.0/parser/expat/lib/internal.h.expat-CVE-2023-52425 2024-03-11 20:36:11.000000000 +0100 -+++ firefox-115.9.0/parser/expat/lib/internal.h 2024-03-14 00:14:39.334319725 +0100 -@@ -80,6 +80,7 @@ - # endif - #endif - -+#include "expat.h" // so we can use type XML_Parser below - - #ifdef __cplusplus - extern "C" { -@@ -90,6 +91,9 @@ void - align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef); - - -+extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c -+extern unsigned int g_parseAttempts; // used for testing only -+ - #ifdef __cplusplus - } - #endif ---- firefox-115.9.0/parser/expat/lib/xmlparse.c.expat-CVE-2023-52425 2024-03-11 20:36:11.000000000 +0100 -+++ firefox-115.9.0/parser/expat/lib/xmlparse.c 2024-03-13 22:55:14.844756009 +0100 -@@ -6,6 +6,7 @@ - - #define _GNU_SOURCE /* syscall prototype */ - -+#include - #include - #include /* memset(), memcpy() */ - #include -@@ -89,6 +90,9 @@ typedef char ICHAR; - /* Round up n to be a multiple of sz, where sz is a power of 2. */ - #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) - -+/* Do safe (NULL-aware) pointer arithmetic */ -+#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) -+ - /* Handle the case where memmove() doesn't exist. */ - #ifndef HAVE_MEMMOVE - #ifdef HAVE_BCOPY -@@ -98,6 +102,8 @@ typedef char ICHAR; - #endif /* HAVE_BCOPY */ - #endif /* HAVE_MEMMOVE */ - -+#define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b)) -+ - #include "internal.h" - #include "xmltok.h" - #include "xmlrole.h" -@@ -476,6 +482,9 @@ parserInit(XML_Parser parser, const XML_ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) - -+XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c -+unsigned int g_parseAttempts = 0; // used for testing only -+ - struct XML_ParserStruct { - /* The first member must be userData so that the XML_GetUserData - macro works. */ -@@ -491,6 +500,9 @@ 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_Bool m_reparseDeferralEnabled; -+ int m_lastBufferRequestSize; - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; -@@ -647,6 +659,9 @@ struct XML_ParserStruct { - #define bufferEnd (parser->m_bufferEnd) - #define parseEndByteIndex (parser->m_parseEndByteIndex) - #define parseEndPtr (parser->m_parseEndPtr) -+#define partialTokenBytesBefore (parser->m_partialTokenBytesBefore) -+#define reparseDeferralEnabled (parser->m_reparseDeferralEnabled) -+#define lastBufferRequestSize (parser->m_lastBufferRequestSize) - #define bufferLim (parser->m_bufferLim) - #define dataBuf (parser->m_dataBuf) - #define dataBufEnd (parser->m_dataBufEnd) -@@ -887,6 +902,47 @@ 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_reparseDeferralEnabled -+ && ! 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; -+ // ...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 -+ available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES); -+#endif -+ 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 -+ const bool enough -+ = (have_now >= 2 * had_before) -+ || ((size_t)parser->m_lastBufferRequestSize > available_buffer); -+ -+ if (! enough) { -+ *endPtr = start; // callers may expect this to be set -+ return XML_ERROR_NONE; -+ } -+ } -+ g_parseAttempts += 1; -+ const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); -+ 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; -+} -+ - static XML_Bool /* only valid for root parser */ - startParsing(XML_Parser parser) - { -@@ -1075,6 +1131,9 @@ parserInit(XML_Parser parser, const XML_ - bufferEnd = buffer; - parseEndByteIndex = 0; - parseEndPtr = NULL; -+ partialTokenBytesBefore = 0; -+ reparseDeferralEnabled = g_reparseDeferralEnabledDefault; -+ lastBufferRequestSize = 0; - declElementType = NULL; - declAttributeId = NULL; - declEntity = NULL; -@@ -1232,6 +1291,7 @@ XML_ExternalEntityParserCreate(XML_Parse - 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) -@@ -1276,6 +1336,7 @@ XML_ExternalEntityParserCreate(XML_Parse - to worry which hash secrets each table has. - */ - oldhash_secret_salt = hash_secret_salt; -+ oldReparseDeferralEnabled = reparseDeferralEnabled; - - #ifdef XML_DTD - if (!context) -@@ -1330,6 +1391,7 @@ XML_ExternalEntityParserCreate(XML_Parse - defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - ns_triplets = oldns_triplets; - hash_secret_salt = oldhash_secret_salt; -+ reparseDeferralEnabled = oldReparseDeferralEnabled; - parentParser = oldParser; - #ifdef XML_DTD - paramEntityParsing = oldParamEntityParsing; -@@ -1850,39 +1912,8 @@ XML_Parse(XML_Parser parser, const char - ps_parsing = XML_PARSING; - } - -- if (len == 0) { -- ps_finalBuffer = (XML_Bool)isFinal; -- if (!isFinal) -- return XML_STATUS_OK; -- positionPtr = bufferPtr; -- parseEndPtr = 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. -- */ -- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); -- -- if (errorCode == XML_ERROR_NONE) { -- switch (ps_parsing) { -- case XML_SUSPENDED: -- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); -- positionPtr = bufferPtr; -- return XML_STATUS_SUSPENDED; -- case XML_INITIALIZED: -- case XML_PARSING: -- ps_parsing = XML_FINISHED; -- /* fall through */ -- default: -- return XML_STATUS_OK; -- } -- } -- eventEndPtr = eventPtr; -- processor = errorProcessor; -- return XML_STATUS_ERROR; -- } - #ifndef XML_CONTEXT_BYTES -- else if (bufferPtr == bufferEnd) { -+ if (bufferPtr == bufferEnd) { - const char *end; - int nLeftOver; - enum XML_Status result; -@@ -1899,11 +1930,14 @@ XML_Parse(XML_Parser parser, const char - 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. -+ lastBufferRequestSize = len; - parseEndByteIndex += len; - positionPtr = s; - ps_finalBuffer = (XML_Bool)isFinal; - -- errorCode = processor(parser, s, parseEndPtr = s + len, &end); -+ errorCode = callProcessor(parser, s, parseEndPtr = s + len, &end); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; -@@ -1930,6 +1964,8 @@ XML_Parse(XML_Parser parser, const char - XmlUpdatePosition(encoding, positionPtr, end, &position); - nLeftOver = s + len - end; - if (nLeftOver) { -+#if 0 -+// erAck: replace with XML_GetBuffer() below. - if (buffer == NULL || nLeftOver > bufferLim - buffer) { - /* avoid _signed_ integer overflow */ - char *temp = NULL; -@@ -1939,6 +1975,28 @@ XML_Parse(XML_Parser parser, const char - ? (char *)MALLOC(bytesToAllocate) - : (char *)REALLOC(buffer, bytesToAllocate)); - } -+#endif -+#if 1 -+// erAck: the original patch context had a call to XML_GetBuffer() instead: -+ // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED -+ // (and XML_ERROR_FINISHED) from XML_GetBuffer. -+ const enum XML_Parsing originalStatus = ps_parsing; -+ ps_parsing = XML_PARSING; -+ void *const temp = XML_GetBuffer(parser, nLeftOver); -+ ps_parsing = originalStatus; -+#endif -+ // GetBuffer may have overwritten this, but we want to remember what the -+ // app requested, not how many bytes were left over after parsing. -+ lastBufferRequestSize = len; -+#if 1 -+ if (temp == NULL) { -+ // NOTE: parser->m_errorCode has already been set by XML_GetBuffer(). -+ eventPtr = eventEndPtr = NULL; -+ processor = errorProcessor; -+ return XML_STATUS_ERROR; -+ } -+#endif -+#if 0 - if (temp == NULL) { - errorCode = XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = NULL; -@@ -1948,6 +2006,7 @@ XML_Parse(XML_Parser parser, const char - buffer = temp; - bufferLim = buffer + bytesToAllocate; - } -+#endif - memcpy(buffer, end, nLeftOver); - } - bufferPtr = buffer; -@@ -1959,15 +2018,14 @@ XML_Parse(XML_Parser parser, const char - 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 -@@ -2001,7 +2059,7 @@ XML_ParseBuffer(XML_Parser parser, int l - parseEndByteIndex += len; - ps_finalBuffer = (XML_Bool)isFinal; - -- errorCode = processor(parser, start, parseEndPtr, &bufferPtr); -+ errorCode = callProcessor(parser, start, parseEndPtr, &bufferPtr); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; -@@ -2047,7 +2105,11 @@ XML_GetBuffer(XML_Parser parser, int len - default: ; - } - -- if (len > bufferLim - bufferEnd) { -+ // whether or not the request succeeds, `len` seems to be the app's preferred -+ // buffer fill size; remember it. -+ lastBufferRequestSize = len; -+ if (len > EXPAT_SAFE_PTR_DIFF(bufferLim, bufferEnd) -+ || buffer == NULL) { - #ifdef XML_CONTEXT_BYTES - int keep; - #endif /* defined XML_CONTEXT_BYTES */ -@@ -2063,7 +2125,9 @@ XML_GetBuffer(XML_Parser parser, int len - keep = XML_CONTEXT_BYTES; - neededSize += keep; - #endif /* defined XML_CONTEXT_BYTES */ -- if (neededSize <= bufferLim - buffer) { -+ if (buffer && bufferPtr -+ && neededSize -+ <= EXPAT_SAFE_PTR_DIFF(bufferLim, buffer)) { - #ifdef XML_CONTEXT_BYTES - if (keep < bufferPtr - buffer) { - int offset = (int)(bufferPtr - buffer) - keep; -@@ -2072,8 +2136,11 @@ XML_GetBuffer(XML_Parser parser, int len - bufferPtr -= offset; - } - #else -- memmove(buffer, bufferPtr, bufferEnd - bufferPtr); -- bufferEnd = buffer + (bufferEnd - bufferPtr); -+ memmove(buffer, bufferPtr, -+ EXPAT_SAFE_PTR_DIFF(bufferEnd, bufferPtr)); -+ bufferEnd -+ = buffer -+ + EXPAT_SAFE_PTR_DIFF(bufferEnd, bufferPtr); - bufferPtr = buffer; - #endif /* not defined XML_CONTEXT_BYTES */ - } -@@ -2171,7 +2238,7 @@ XML_ResumeParser(XML_Parser parser) - } - ps_parsing = XML_PARSING; - -- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); -+ errorCode = callProcessor(parser, bufferPtr, parseEndPtr, &bufferPtr); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; -@@ -2481,6 +2548,15 @@ MOZ_XML_ProcessingEntityValue(XML_Parser - } - /* END MOZILLA CHANGE */ - -+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 diff --git a/SPECS/firefox.spec b/SPECS/firefox.spec index 1872cf4..30c0be3 100644 --- a/SPECS/firefox.spec +++ b/SPECS/firefox.spec @@ -133,7 +133,7 @@ end} Summary: Mozilla Firefox Web browser Name: firefox Version: 115.9.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ @@ -237,7 +237,6 @@ Patch201: firefox-tests-xpcshell-freeze.patch # ---- Security patches ---- Patch301: CVE-2023-44488-libvpx.patch -Patch302: expat-CVE-2023-52425.patch # BUILD REQURES/REQUIRES %if %{?system_nss} && !0%{?bundle_nss} @@ -1048,7 +1047,6 @@ echo "--------------------------------------------" cd media/libvpx/libvpx %patch -P301 -p1 -b .CVE-2023-44488-libvpx cd - -%patch -P302 -p1 -b .expat-CVE-2023-52425 %{__rm} -f .mozconfig %{__cp} %{SOURCE10} .mozconfig @@ -1742,6 +1740,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Tue Apr 09 2024 Jan Horak - 115.9.1-2 +- Removed expat CVE fix + * Fri Mar 22 2024 Eike Rathke - 115.9.1-1 - Update to 115.9.1