Be defensive about overflows in stream objects

We use a lot of lengths given to us over the network, so be more
paranoid about them causing an overflow as otherwise an attacker
might trick us in to overwriting other memory.

This primarily affects the client which often gets lengths from the
server, but there are also some scenarios where the server might
theoretically be vulnerable.

Issue found by Pavel Cheremushkin from Kaspersky Lab.
This commit is contained in:
Pierre Ossman
2019-09-24 09:41:07 +02:00
committed by Lauri Kasanen
parent 259f1055cb
commit ae6cbd19e9
13 changed files with 75 additions and 48 deletions

View File

@@ -43,12 +43,15 @@ namespace rdr {
inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
{
if (ptr + itemSize * nItems > end) {
if (ptr + itemSize > end)
return overrun(itemSize, nItems, wait);
size_t nAvail;
if (itemSize > (size_t)(end - ptr))
return overrun(itemSize, nItems, wait);
nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
nItems = (end - ptr) / itemSize;
}
return nItems;
}
@@ -93,13 +96,12 @@ namespace rdr {
// readBytes() reads an exact number of bytes.
void readBytes(void* data, size_t length) {
U8* dataPtr = (U8*)data;
U8* dataEnd = dataPtr + length;
while (dataPtr < dataEnd) {
size_t n = check(1, dataEnd - dataPtr);
memcpy(dataPtr, ptr, n);
while (length > 0) {
size_t n = check(1, length);
memcpy(data, ptr, n);
ptr += n;
dataPtr += n;
data = (U8*)data + n;
length -= n;
}
}