Merge pull request #534 from libexpat/issue-531-troublesome-shifts

[CVE-2021-45960] lib: Detect and prevent troublesome left shifts in function storeAtts (fixes #531)
This commit is contained in:
Sebastian Pipping 2022-01-07 23:17:01 +01:00 committed by GitHub
commit 9dc50735f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 2 deletions

View file

@ -3,6 +3,20 @@ NOTE: We are looking for help with a few things:
If you can help, please get in touch. Thanks!
Release x.x.x xxx xxxxxxxx xx xxxx
Security fixes:
#531 #534 CVE-2021-45960 -- Fix issues with left shifts by >=29 places
resulting in
a) realloc acting as free
b) realloc allocating too few bytes
c) undefined behavior
depending on architecture and precise value
for XML documents with >=2^27+1 prefixed attributes
on a single XML tag a la
"<r xmlns:a='[..]' a:a123='[..]' [..] />"
where XML_ParserCreateNS is used to create the parser
(which needs argument "-n" when running xmlwf).
Impact is denial of service, or more.
Other changes:
#535 CMake: Make call to file(GENERATE [..]) work for CMake <3.19
#527 #528 Address compiler warnings
@ -10,6 +24,11 @@ Release x.x.x xxx xxxxxxxx xx xxxx
Infrastructure:
#536 CI: Check for realistic minimum CMake version
Special thanks to:
Tyson Smith
and
GCC Farm Project
Release 2.4.2 Sun December 19 2021
Other changes:
#509 #510 Link againgst libm for function "isnan"

View file

@ -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) {