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:
committed by
Lauri Kasanen
parent
259f1055cb
commit
ae6cbd19e9
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user