From c58726acaac16347bae2be847e622d18cf726d51 Mon Sep 17 00:00:00 2001 From: jlwwlsqc Date: Sat, 15 Jan 2022 16:15:09 +0800 Subject: [PATCH] fix CVE-2021-45960 CVE-2021-46143 CVE-2022-22822 CVE-2022-22823 CVE-2022-22824 CVE-2022-22825 CVE-2022-22826 CVE-2022-22827 --- backport-CVE-2021-45960.patch | 62 +++++ backport-CVE-2021-46143.patch | 46 ++++ ...-22825-CVE-2022-22826-CVE-2022-22827.patch | 253 ++++++++++++++++++ expat.spec | 12 +- 4 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-45960.patch create mode 100644 backport-CVE-2021-46143.patch create mode 100644 backport-CVE-2022-22822-CVE-2022-22823-CVE-2022-22824-CVE-2022-22825-CVE-2022-22826-CVE-2022-22827.patch diff --git a/backport-CVE-2021-45960.patch b/backport-CVE-2021-45960.patch new file mode 100644 index 0000000..6dad864 --- /dev/null +++ b/backport-CVE-2021-45960.patch @@ -0,0 +1,62 @@ +From 0adcb34c49bee5b19bd29b16a578c510c23597ea Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Mon, 27 Dec 2021 20:15:02 +0100 +Subject: [PATCH] lib: Detect and prevent troublesome left shifts in function + storeAtts (CVE-2021-45960) + +--- + lib/xmlparse.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index d730f41..b47c31b 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -3414,7 +3414,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + 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) +@@ -3425,7 +3431,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + ; + 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) { +-- +1.8.3.1 + diff --git a/backport-CVE-2021-46143.patch b/backport-CVE-2021-46143.patch new file mode 100644 index 0000000..2498b9a --- /dev/null +++ b/backport-CVE-2021-46143.patch @@ -0,0 +1,46 @@ +From 85ae9a2d7d0e9358f356b33977b842df8ebaec2b Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Sat, 25 Dec 2021 20:52:08 +0100 +Subject: [PATCH] lib: Prevent integer overflow on m_groupSize in function + doProlog (CVE-2021-46143) + +--- + lib/xmlparse.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index b47c31b..8f24312 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -5046,6 +5046,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + 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 *const new_connector = (char *)REALLOC( + parser, parser->m_groupConnector, parser->m_groupSize *= 2); + if (new_connector == NULL) { +@@ -5056,6 +5061,16 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + } + + 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 *const new_scaff_index = (int *)REALLOC( + parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); + if (new_scaff_index == NULL) +-- +1.8.3.1 + diff --git a/backport-CVE-2022-22822-CVE-2022-22823-CVE-2022-22824-CVE-2022-22825-CVE-2022-22826-CVE-2022-22827.patch b/backport-CVE-2022-22822-CVE-2022-22823-CVE-2022-22824-CVE-2022-22825-CVE-2022-22826-CVE-2022-22827.patch new file mode 100644 index 0000000..d543f48 --- /dev/null +++ b/backport-CVE-2022-22822-CVE-2022-22823-CVE-2022-22824-CVE-2022-22825-CVE-2022-22826-CVE-2022-22827.patch @@ -0,0 +1,253 @@ +From 9f93e8036e842329863bf20395b8fb8f73834d9e Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Thu, 30 Dec 2021 22:46:03 +0100 +Subject: [PATCH] lib: Prevent integer overflow at multiple places + (CVE-2022-22822 to CVE-2022-22827) + +The involved functions are: +- addBinding (CVE-2022-22822) +- build_model (CVE-2022-22823) +- defineAttribute (CVE-2022-22824) +- lookup (CVE-2022-22825) +- nextScaffoldPart (CVE-2022-22826) +- storeAtts (CVE-2022-22827) +--- + lib/xmlparse.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 151 insertions(+), 2 deletions(-) + +diff --git a/lib/xmlparse.c b/lib/xmlparse.c +index 8f24312..575e73e 100644 +--- a/lib/xmlparse.c ++++ b/lib/xmlparse.c +@@ -3261,13 +3261,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + + /* 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) { +@@ -3276,6 +3301,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + } + 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) { +@@ -3610,9 +3646,31 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + 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; +@@ -3708,6 +3766,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) +@@ -3720,6 +3793,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) { +@@ -6141,7 +6229,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) +@@ -6792,8 +6897,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) +@@ -7143,6 +7260,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) +@@ -7212,8 +7343,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) +-- +1.8.3.1 + diff --git a/expat.spec b/expat.spec index e15ae0c..46d32e1 100644 --- a/expat.spec +++ b/expat.spec @@ -1,7 +1,7 @@ %define Rversion %(echo %{version} | sed -e 's/\\./_/g' -e 's/^/R_/') Name: expat Version: 2.2.9 -Release: 3 +Release: 4 Summary: An XML parser library License: MIT URL: https://libexpat.github.io/ @@ -29,6 +29,9 @@ Patch17: backport-CVE-2013-0340-tests-Cover-helper-unsignedCharToPrintabl Patch18: backport-CVE-2013-0340-tests-Cover-accounting-of-CDATA-sections.patch Patch19: backport-CVE-2013-0340-lib-Fix-accounting-of-CDATA-sections-inside.patch Patch20: backport-xmlparse.c-Fix-reading-uninitialized-variable-404.patch +Patch21: backport-CVE-2021-45960.patch +Patch22: backport-CVE-2021-46143.patch +Patch23: backport-CVE-2022-22822-CVE-2022-22823-CVE-2022-22824-CVE-2022-22825-CVE-2022-22826-CVE-2022-22827.patch BuildRequires: sed,autoconf,automake,gcc-c++,libtool,xmlto @@ -81,6 +84,13 @@ make check %{_mandir}/man1/* %changelog +* Mon Jan 17 2022 wangjie - 2.2.9-4 +- Type:CVE +- ID:CVE-2021-45960 CVE-2021-46143 CVE-2022-22822 CVE-2022-22823 CVE-2022-22824 CVE-2022-22825 CVE-2022-22826 CVE-2022-22827 +- SUG:NA +- DESC:fix CVE-2021-45960 CVE-2021-46143 + CVE-2022-22822 CVE-2022-22823 CVE-2022-22824 CVE-2022-22825 CVE-2022-22826 CVE-2022-22827 + * Fri Jul 2 2021 panxiaohe - 2.2.9-3 - fix CVE-2013-0340 - xmlparse.c: Fix reading uninitialized variable -- Gitee