Copied from Debian. Description: fix multiple integer overflows in the XML_GetBuffer function Multiple integer overflows in the XML_GetBuffer function in Expat through 2.1.0, as used in Google Chrome before 44.0.2403.89 and other products, allow remote attackers to cause a denial of service (heap-based buffer overflow) or possibly have unspecified other impact via crafted XML data, a related issue to CVE-2015-2716. Origin: Mozilla, https://hg.mozilla.org/releases/mozilla-esr31/rev/2f3e78643f5c Author: Eric Rahm Forwarded: not-needed Last-Update: 2015-07-24 diff --git a/lib/xmlparse.c b/lib/xmlparse.c --- a/lib/xmlparse.c +++ b/lib/xmlparse.c @@ -1673,29 +1673,40 @@ XML_ParseBuffer(XML_Parser parser, int l XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); positionPtr = bufferPtr; return result; } void * XMLCALL XML_GetBuffer(XML_Parser parser, int len) { +/* BEGIN MOZILLA CHANGE (sanity check len) */ + if (len < 0) { + errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } +/* END MOZILLA CHANGE */ switch (ps_parsing) { case XML_SUSPENDED: errorCode = XML_ERROR_SUSPENDED; return NULL; case XML_FINISHED: errorCode = XML_ERROR_FINISHED; return NULL; default: ; } if (len > bufferLim - bufferEnd) { - /* FIXME avoid integer overflow */ int neededSize = len + (int)(bufferEnd - bufferPtr); +/* BEGIN MOZILLA CHANGE (sanity check neededSize) */ + if (neededSize < 0) { + errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } +/* END MOZILLA CHANGE */ #ifdef XML_CONTEXT_BYTES int keep = (int)(bufferPtr - buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; neededSize += keep; #endif /* defined XML_CONTEXT_BYTES */ if (neededSize <= bufferLim - buffer) { @@ -1714,17 +1725,25 @@ XML_GetBuffer(XML_Parser parser, int len } else { char *newBuf; int bufferSize = (int)(bufferLim - bufferPtr); if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { bufferSize *= 2; - } while (bufferSize < neededSize); +/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */ + } while (bufferSize < neededSize && bufferSize > 0); +/* END MOZILLA CHANGE */ +/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */ + if (bufferSize <= 0) { + errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } +/* END MOZILLA CHANGE */ newBuf = (char *)MALLOC(bufferSize); if (newBuf == 0) { errorCode = XML_ERROR_NO_MEMORY; return NULL; } bufferLim = newBuf + bufferSize; #ifdef XML_CONTEXT_BYTES if (bufferPtr) {