Преглед на файлове

Make ZlibInStream more robust against failures

Move the checks around to avoid missing cases where we might access
memory that is no longer valid. Also avoid touching the underlying
stream implicitly (e.g. via the destructor) as it might also no
longer be valid.

A malicious server could theoretically use this for remote code
execution in the client.

Issue found by Pavel Cheremushkin from Kaspersky Lab
tags/v1.10.90
Pierre Ossman преди 4 години
родител
ревизия
d61a767d68
променени са 6 файла, в които са добавени 16 реда и са изтрити 11 реда
  1. 7
    6
      common/rdr/ZlibInStream.cxx
  2. 1
    1
      common/rdr/ZlibInStream.h
  3. 2
    1
      common/rfb/CMsgReader.cxx
  4. 2
    1
      common/rfb/SMsgReader.cxx
  5. 2
    1
      common/rfb/TightDecoder.cxx
  6. 2
    1
      common/rfb/zrleDecode.h

+ 7
- 6
common/rdr/ZlibInStream.cxx Целия файл

@@ -52,16 +52,16 @@ int ZlibInStream::pos()
return offset + ptr - start;
}

void ZlibInStream::removeUnderlying()
void ZlibInStream::flushUnderlying()
{
ptr = end = start;
if (!underlying) return;

while (bytesIn > 0) {
decompress(true);
end = start; // throw away any data
}
underlying = 0;

setUnderlying(NULL, 0);
}

void ZlibInStream::reset()
@@ -90,7 +90,7 @@ void ZlibInStream::init()
void ZlibInStream::deinit()
{
assert(zs != NULL);
removeUnderlying();
setUnderlying(NULL, 0);
inflateEnd(zs);
delete zs;
zs = NULL;
@@ -100,8 +100,6 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
{
if (itemSize > bufSize)
throw Exception("ZlibInStream overrun: max itemSize exceeded");
if (!underlying)
throw Exception("ZlibInStream overrun: no underlying stream");

if (end - ptr != 0)
memmove(start, ptr, end - ptr);
@@ -127,6 +125,9 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)

bool ZlibInStream::decompress(bool wait)
{
if (!underlying)
throw Exception("ZlibInStream overrun: no underlying stream");

zs->next_out = (U8*)end;
zs->avail_out = start + bufSize - end;


+ 1
- 1
common/rdr/ZlibInStream.h Целия файл

@@ -38,7 +38,7 @@ namespace rdr {
virtual ~ZlibInStream();

void setUnderlying(InStream* is, int bytesIn);
void removeUnderlying();
void flushUnderlying();
int pos();
void reset();


+ 2
- 1
common/rfb/CMsgReader.cxx Целия файл

@@ -242,7 +242,8 @@ void CMsgReader::readExtendedClipboard(rdr::S32 len)
num++;
}

zis.removeUnderlying();
zis.flushUnderlying();
zis.setUnderlying(NULL, 0);

handler->handleClipboardProvide(flags, lengths, buffers);


+ 2
- 1
common/rfb/SMsgReader.cxx Целия файл

@@ -293,7 +293,8 @@ void SMsgReader::readExtendedClipboard(rdr::S32 len)
num++;
}

zis.removeUnderlying();
zis.flushUnderlying();
zis.setUnderlying(NULL, 0);

handler->handleClipboardProvide(flags, lengths, buffers);


+ 2
- 1
common/rfb/TightDecoder.cxx Целия файл

@@ -341,7 +341,8 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,

zis[streamId].readBytes(netbuf, dataSize);

zis[streamId].removeUnderlying();
zis[streamId].flushUnderlying();
zis[streamId].setUnderlying(NULL, 0);
delete ms;

bufptr = netbuf;

+ 2
- 1
common/rfb/zrleDecode.h Целия файл

@@ -174,7 +174,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
}
}

zis->removeUnderlying();
zis->flushUnderlying();
zis->setUnderlying(NULL, 0);
}

#undef ZRLE_DECODE

Loading…
Отказ
Запис