Skip to content

Commit

Permalink
lib: Detect and prevent troublesome left shifts in function storeAtts (
Browse files Browse the repository at this point in the history
  • Loading branch information
hartwork committed Jan 2, 2022
1 parent 5cde0d7 commit ef181d9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
19 changes: 19 additions & 0 deletions expat/Changes
Expand Up @@ -3,13 +3,32 @@ 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

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"
Expand Down
31 changes: 29 additions & 2 deletions expat/lib/xmlparse.c
Expand Up @@ -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)
Expand All @@ -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) {
Expand Down

0 comments on commit ef181d9

Please sign in to comment.