diff --git a/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch b/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch new file mode 100644 index 0000000..4ea8add --- /dev/null +++ b/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch @@ -0,0 +1,183 @@ +commit 22fe2da8e2bc0625d3c492f42d6b716adb36d5c2 +Author: Tomas Korbar +Date: Mon Feb 14 12:09:42 2022 +0100 + + CVE-2022-23852 + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 85ee0a8..4552680 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -161,6 +161,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 +@@ -2026,39 +2029,54 @@ XML_GetBuffer(XML_Parser parser, int len) + default: ; + } + +- if (len > parser->m_bufferLim - parser->m_bufferEnd) { +-#ifdef XML_CONTEXT_BYTES ++ if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { + int keep; +-#endif /* defined XML_CONTEXT_BYTES */ + /* Do not invoke signed arithmetic overflow: */ +- int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr)); ++ int neededSize = (int)((unsigned)len ++ + (unsigned)EXPAT_SAFE_PTR_DIFF( ++ parser->m_bufferEnd, parser->m_bufferPtr)); + if (neededSize < 0) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } +-#ifdef XML_CONTEXT_BYTES +- keep = (int)(parser->m_bufferPtr - parser->m_buffer); ++ ++ keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); + if (keep > XML_CONTEXT_BYTES) + keep = XML_CONTEXT_BYTES; ++ /* Detect and prevent integer overflow */ ++ if (keep > INT_MAX - neededSize) { ++ parser->m_errorCode = XML_ERROR_NO_MEMORY; ++ return NULL; ++ } + neededSize += keep; +-#endif /* defined XML_CONTEXT_BYTES */ +- if (neededSize <= parser->m_bufferLim - parser->m_buffer) { ++ if (neededSize ++ <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { + #ifdef XML_CONTEXT_BYTES +- if (keep < parser->m_bufferPtr - parser->m_buffer) { +- int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep; +- memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); ++ if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { ++ int offset ++ = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) ++ - keep; ++ /* The buffer pointers cannot be NULL here; we have at least some bytes ++ * in the buffer */ ++ memmove(parser->m_buffer, &parser->m_buffer[offset], ++ parser->m_bufferEnd - parser->m_bufferPtr + keep); + parser->m_bufferEnd -= offset; + parser->m_bufferPtr -= offset; + } + #else +- memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); +- parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr); +- parser->m_bufferPtr = parser->m_buffer; +-#endif /* not defined XML_CONTEXT_BYTES */ +- } +- 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; ++ } ++#endif /* not defined XML_CONTEXT_BYTES */ ++ } else { + char *newBuf; +- int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr); ++ int bufferSize ++ = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); + if (bufferSize == 0) + bufferSize = INIT_BUFFER_SIZE; + do { +@@ -2077,25 +2095,33 @@ XML_GetBuffer(XML_Parser parser, int len) + parser->m_bufferLim = newBuf + bufferSize; + #ifdef XML_CONTEXT_BYTES + if (parser->m_bufferPtr) { +- int keep = (int)(parser->m_bufferPtr - parser->m_buffer); +- if (keep > XML_CONTEXT_BYTES) +- keep = XML_CONTEXT_BYTES; +- memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep); ++ memcpy(newBuf, &parser->m_bufferPtr[-keep], ++ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) ++ + keep); + FREE(parser, parser->m_buffer); + parser->m_buffer = newBuf; +- parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep; ++ parser->m_bufferEnd ++ = parser->m_buffer ++ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) ++ + keep; + parser->m_bufferPtr = parser->m_buffer + keep; +- } +- else { +- parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); ++ } else { ++ /* This must be a brand new buffer with no data in it yet */ ++ parser->m_bufferEnd = newBuf; + parser->m_bufferPtr = parser->m_buffer = newBuf; + } + #else + if (parser->m_bufferPtr) { +- memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); ++ memcpy(newBuf, parser->m_bufferPtr, ++ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); + FREE(parser, parser->m_buffer); ++ parser->m_bufferEnd ++ = newBuf ++ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); ++ } else { ++ /* This must be a brand new buffer with no data in it yet */ ++ parser->m_bufferEnd = newBuf; + } +- parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); + parser->m_bufferPtr = parser->m_buffer = newBuf; + #endif /* not defined XML_CONTEXT_BYTES */ + } +diff --git a/tests/runtests.c b/tests/runtests.c +index e1f1ad1..ecc6f47 100644 +--- a/tests/runtests.c ++++ b/tests/runtests.c +@@ -4116,6 +4116,31 @@ START_TEST(test_get_buffer_2) + } + END_TEST + ++/* Test for signed integer overflow CVE-2022-23852 */ ++#if defined(XML_CONTEXT_BYTES) ++START_TEST(test_get_buffer_3_overflow) { ++ XML_Parser parser = XML_ParserCreate(NULL); ++ assert(parser != NULL); ++ ++ const char *const text = "\n"; ++ const int expectedKeepValue = (int)strlen(text); ++ ++ // After this call, variable "keep" in XML_GetBuffer will ++ // have value expectedKeepValue ++ if (XML_Parse(parser, text, (int)strlen(text), XML_FALSE /* isFinal */) ++ == XML_STATUS_ERROR) ++ xml_failure(parser); ++ ++ assert(expectedKeepValue > 0); ++ if (XML_GetBuffer(parser, INT_MAX - expectedKeepValue + 1) != NULL) ++ fail("enlarging buffer not failed"); ++ ++ XML_ParserFree(parser); ++} ++END_TEST ++#endif // defined(XML_CONTEXT_BYTES) ++ ++ + /* Test position information macros */ + START_TEST(test_byte_info_at_end) + { +@@ -12117,6 +12142,9 @@ make_suite(void) + tcase_add_test(tc_basic, test_empty_parse); + tcase_add_test(tc_basic, test_get_buffer_1); + tcase_add_test(tc_basic, test_get_buffer_2); ++#if defined(XML_CONTEXT_BYTES) ++ tcase_add_test(tc_basic, test_get_buffer_3_overflow); ++#endif + tcase_add_test(tc_basic, test_byte_info_at_end); + tcase_add_test(tc_basic, test_byte_info_at_error); + tcase_add_test(tc_basic, test_byte_info_at_cdata); diff --git a/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch b/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch new file mode 100644 index 0000000..cfb28fb --- /dev/null +++ b/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch @@ -0,0 +1,54 @@ +commit dbac77ddbccb23d507758c591fad622e2b6e6324 +Author: Tomas Korbar +Date: Mon Feb 14 12:20:25 2022 +0100 + + CVE-2021-45960 + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 2821c6f..c45be0c 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -3341,7 +3341,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + if (nPrefixes) { + int j; /* hash table index */ + unsigned long version = parser->m_nsAttsVersion; +- int nsAttsSize = (int)1 << parser->m_nsAttsPower; ++ /* Detect and prevent invalid shift */ ++ if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ ++ unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; + unsigned char oldNsAttsPower = parser->m_nsAttsPower; + /* size of hash table must be at least 2 * (# of prefixed attributes) */ + if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ +@@ -3350,7 +3355,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + while (nPrefixes >> parser->m_nsAttsPower++); + if (parser->m_nsAttsPower < 3) + parser->m_nsAttsPower = 3; +- nsAttsSize = (int)1 << parser->m_nsAttsPower; ++ ++ /* Detect and prevent invalid shift */ ++ if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { ++ /* Restore actual size of memory in m_nsAtts */ ++ parser->m_nsAttsPower = oldNsAttsPower; ++ return XML_ERROR_NO_MEMORY; ++ } ++ ++ nsAttsSize = 1u << parser->m_nsAttsPower; ++ ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { ++ /* Restore actual size of memory in m_nsAtts */ ++ parser->m_nsAttsPower = oldNsAttsPower; ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif ++ + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); + if (!temp) { + /* Restore actual size of memory in m_nsAtts */ diff --git a/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch b/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch new file mode 100644 index 0000000..f7e76e6 --- /dev/null +++ b/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch @@ -0,0 +1,38 @@ +commit 835df27bc1a1eae1ec51b14122ea40c974dd7409 +Author: Tomas Korbar +Date: Mon Feb 14 12:29:20 2022 +0100 + + CVE-2021-46143 + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index c45be0c..22d0a75 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -4995,6 +4995,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + case XML_ROLE_GROUP_OPEN: + if (parser->m_prologState.level >= parser->m_groupSize) { + if (parser->m_groupSize) { ++ /* Detect and prevent integer overflow */ ++ if (parser->m_groupSize > (unsigned int)(-1) / 2u) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ + char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2); + if (temp == NULL) { + parser->m_groupSize /= 2; +@@ -5002,6 +5007,15 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + } + parser->m_groupConnector = temp; + if (dtd->scaffIndex) { ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif + int *temp = (int *)REALLOC(parser, dtd->scaffIndex, + parser->m_groupSize * sizeof(int)); + if (temp == NULL) diff --git a/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch b/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch new file mode 100644 index 0000000..45e3f8d --- /dev/null +++ b/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch @@ -0,0 +1,238 @@ +commit 0f920007dc157e052fed2fc66a83c6c23ccec0aa +Author: Tomas Korbar +Date: Mon Feb 14 12:41:56 2022 +0100 + + CVE-2022-22822 to CVE-2022-22827 + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 22d0a75..6a880af 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -3187,13 +3187,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + + /* get the attributes from the tokenizer */ + n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); ++ ++ /* Detect and prevent integer overflow */ ++ if (n > INT_MAX - nDefaultAtts) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ + if (n + nDefaultAtts > parser->m_attsSize) { + int oldAttsSize = parser->m_attsSize; + ATTRIBUTE *temp; + #ifdef XML_ATTR_INFO + XML_AttrInfo *temp2; + #endif ++ ++ /* Detect and prevent integer overflow */ ++ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) ++ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ + parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; ++ ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { ++ parser->m_attsSize = oldAttsSize; ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif ++ + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); + if (temp == NULL) { + parser->m_attsSize = oldAttsSize; +@@ -3201,6 +3226,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + } + parser->m_atts = temp; + #ifdef XML_ATTR_INFO ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++# if UINT_MAX >= SIZE_MAX ++ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { ++ parser->m_attsSize = oldAttsSize; ++ return XML_ERROR_NO_MEMORY; ++ } ++# endif ++ + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); + if (temp2 == NULL) { + parser->m_attsSize = oldAttsSize; +@@ -3535,9 +3571,30 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + tagNamePtr->prefixLen = prefixLen; + for (i = 0; localPart[i++];) + ; /* i includes null terminator */ ++ ++ /* Detect and prevent integer overflow */ ++ if (binding->uriLen > INT_MAX - prefixLen ++ || i > INT_MAX - (binding->uriLen + prefixLen)) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ + n = i + binding->uriLen + prefixLen; + if (n > binding->uriAlloc) { + TAG *p; ++ /* Detect and prevent integer overflow */ ++ if (n > INT_MAX - EXPAND_SPARE) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif ++ + uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); + if (!uri) + return XML_ERROR_NO_MEMORY; +@@ -3638,6 +3695,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + if (parser->m_freeBindingList) { + b = parser->m_freeBindingList; + if (len > b->uriAlloc) { ++ /* Detect and prevent integer overflow */ ++ if (len > INT_MAX - EXPAND_SPARE) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif ++ + XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri, + sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (temp == NULL) +@@ -3651,6 +3723,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + b = (BINDING *)MALLOC(parser, sizeof(BINDING)); + if (!b) + return XML_ERROR_NO_MEMORY; ++ ++ /* Detect and prevent integer overflow */ ++ if (len > INT_MAX - EXPAND_SPARE) { ++ return XML_ERROR_NO_MEMORY; ++ } ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { ++ return XML_ERROR_NO_MEMORY; ++ } ++#endif ++ + b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (!b->uri) { + FREE(parser, b); +@@ -6058,7 +6145,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, + } + else { + DEFAULT_ATTRIBUTE *temp; ++ ++ /* Detect and prevent integer overflow */ ++ if (type->allocDefaultAtts > INT_MAX / 2) { ++ return 0; ++ } ++ + int count = type->allocDefaultAtts * 2; ++ ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { ++ return 0; ++ } ++#endif ++ + temp = (DEFAULT_ATTRIBUTE *) + REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); + if (temp == NULL) +@@ -6733,8 +6837,20 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) + /* check for overflow (table is half full) */ + if (table->used >> (table->power - 1)) { + unsigned char newPower = table->power + 1; ++ ++ /* Detect and prevent invalid shift */ ++ if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { ++ return NULL; ++ } ++ + size_t newSize = (size_t)1 << newPower; + unsigned long newMask = (unsigned long)newSize - 1; ++ ++ /* Detect and prevent integer overflow */ ++ if (newSize > (size_t)(-1) / sizeof(NAMED *)) { ++ return NULL; ++ } ++ + size_t tsize = newSize * sizeof(NAMED *); + NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); + if (!newV) +@@ -7100,6 +7216,20 @@ nextScaffoldPart(XML_Parser parser) + if (dtd->scaffCount >= dtd->scaffSize) { + CONTENT_SCAFFOLD *temp; + if (dtd->scaffold) { ++ /* Detect and prevent integer overflow */ ++ if (dtd->scaffSize > UINT_MAX / 2u) { ++ return -1; ++ } ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { ++ return -1; ++ } ++#endif ++ + temp = (CONTENT_SCAFFOLD *) + REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); + if (temp == NULL) +@@ -7176,8 +7306,26 @@ build_model (XML_Parser parser) + XML_Content *ret; + XML_Content *cpos; + XML_Char * str; +- int allocsize = (dtd->scaffCount * sizeof(XML_Content) +- + (dtd->contentStringLen * sizeof(XML_Char))); ++ ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { ++ return NULL; ++ } ++ if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { ++ return NULL; ++ } ++#endif ++ if (dtd->scaffCount * sizeof(XML_Content) ++ > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { ++ return NULL; ++ } ++ ++ const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) ++ + (dtd->contentStringLen * sizeof(XML_Char))); + + ret = (XML_Content *)MALLOC(parser, allocsize); + if (!ret) diff --git a/SPECS/expat.spec b/SPECS/expat.spec index 25338ac..df700a3 100644 --- a/SPECS/expat.spec +++ b/SPECS/expat.spec @@ -3,7 +3,7 @@ Summary: An XML parser library Name: expat Version: %(echo %{unversion} | sed 's/_/./g') -Release: 4%{?dist} +Release: 5%{?dist} Source: https://github.com/libexpat/libexpat/archive/R_%{unversion}.tar.gz#/expat-%{version}.tar.gz URL: https://libexpat.github.io/ License: MIT @@ -11,6 +11,10 @@ BuildRequires: autoconf, libtool, xmlto, gcc-c++ Patch0: expat-2.2.5-doc2man.patch Patch1: expat-2.2.5-CVE-2018-20843.patch Patch2: expat-2.2.5-CVE-2019-15903.patch +Patch3: expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch +Patch4: expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch +Patch5: expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch +Patch6: expat-2.2.5-Prevent-more-integer-overflows.patch %description This is expat, the C library for parsing XML, written by James Clark. Expat @@ -41,6 +45,10 @@ Install it if you need to link statically with expat. %patch0 -p2 -b .doc2man %patch1 -p2 -b .cve20843 %patch2 -p2 -b .cve15903 +%patch3 -p1 -b .CVE-2022-23852 +%patch4 -p1 -b .CVE-2021-45960 +%patch5 -p1 -b .CVE-2021-46143 +%patch6 -p1 -b .CVE-2022-22822-CVE-2022-22827 sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am ./buildconf.sh @@ -79,6 +87,27 @@ make check %{_libdir}/lib*.a %changelog +* Fri Feb 14 2022 Tomas Korbar - 2.2.5-5 +- Fix multiple CVEs +- CVE-2022-23852 expat: integer overflow in function XML_GetBuffer +- CVE-2021-45960 expat: Large number of prefixed XML attributes on a single tag can crash libexpat +- CVE-2021-46143 expat: Integer overflow in doProlog in xmlparse.c +- CVE-2022-22827 Integer overflow in storeAtts in xmlparse.c +- CVE-2022-22826 Integer overflow in nextScaffoldPart in xmlparse.c +- CVE-2022-22825 Integer overflow in lookup in xmlparse.c +- CVE-2022-22824 Integer overflow in defineAttribute in xmlparse.c +- CVE-2022-22823 Integer overflow in build_model in xmlparse.c +- CVE-2022-22822 Integer overflow in addBinding in xmlparse.c +- Resolves: CVE-2022-23852 +- Resolves: CVE-2021-45960 +- Resolves: CVE-2021-46143 +- Resolves: CVE-2022-22827 +- Resolves: CVE-2022-22826 +- Resolves: CVE-2022-22825 +- Resolves: CVE-2022-22824 +- Resolves: CVE-2022-22823 +- Resolves: CVE-2022-22822 + * Fri Apr 24 2020 Joe Orton - 2.2.5-4 - add security fixes for CVE-2018-20843, CVE-2019-15903