Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
tigervnc
0011-Be-defensive-about-overflows-in-stream-obj...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0011-Be-defensive-about-overflows-in-stream-objects.patch of Package tigervnc
From 75e6e0653a48baf474fd45d78b1da53e2f324642 Mon Sep 17 00:00:00 2001 From: Pierre Ossman <ossman@cendio.se> Date: Tue, 24 Sep 2019 09:41:07 +0200 Subject: [PATCH] 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. --- common/rdr/FdInStream.cxx | 8 +++++--- common/rdr/FdOutStream.cxx | 7 ++++--- common/rdr/FileInStream.cxx | 8 +++++--- common/rdr/HexInStream.cxx | 8 +++++--- common/rdr/HexOutStream.cxx | 6 ++++-- common/rdr/InStream.h | 24 +++++++++++++----------- common/rdr/MemOutStream.h | 4 ++++ common/rdr/OutStream.h | 24 +++++++++++++----------- common/rdr/RandomStream.cxx | 6 ++++-- common/rdr/TLSInStream.cxx | 10 ++++++---- common/rdr/TLSOutStream.cxx | 6 ++++-- common/rdr/ZlibInStream.cxx | 6 ++++-- common/rdr/ZlibOutStream.cxx | 6 ++++-- 13 files changed, 75 insertions(+), 48 deletions(-) Index: tigervnc-1.8.0/common/rdr/FdInStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/FdInStream.cxx +++ tigervnc-1.8.0/common/rdr/FdInStream.cxx @@ -136,7 +136,7 @@ size_t FdInStream::overrun(size_t itemSi ptr = start; size_t bytes_to_read; - while (end < start + itemSize) { + while ((size_t)(end - start) < itemSize) { bytes_to_read = start + bufSize - end; if (!timing) { // When not timing, we must be careful not to read too much @@ -152,8 +152,10 @@ size_t FdInStream::overrun(size_t itemSi end += n; } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/FdOutStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/FdOutStream.cxx +++ tigervnc-1.8.0/common/rdr/FdOutStream.cxx @@ -148,9 +148,10 @@ size_t FdOutStream::overrun(size_t itemS } } - // Can we fit all the items asked for? - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/FileInStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/FileInStream.cxx +++ tigervnc-1.8.0/common/rdr/FileInStream.cxx @@ -68,7 +68,7 @@ size_t FileInStream::overrun(size_t item ptr = b; - while (end < b + itemSize) { + while ((size_t)(end - b) < itemSize) { size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file); if (n < 1) { if (n < 0 || ferror(file)) @@ -80,8 +80,10 @@ size_t FileInStream::overrun(size_t item end += b + sizeof(b) - end; } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/HexInStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/HexInStream.cxx +++ tigervnc-1.8.0/common/rdr/HexInStream.cxx @@ -91,7 +91,7 @@ size_t HexInStream::overrun(size_t itemS offset += ptr - start; ptr = start; - while (end < ptr + itemSize) { + while ((size_t)(end - ptr) < itemSize) { size_t n = in_stream.check(2, 1, wait); if (n == 0) return 0; const U8* iptr = in_stream.getptr(); @@ -110,8 +110,10 @@ size_t HexInStream::overrun(size_t itemS end += length; } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/HexOutStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/HexOutStream.cxx +++ tigervnc-1.8.0/common/rdr/HexOutStream.cxx @@ -102,8 +102,10 @@ HexOutStream::overrun(size_t itemSize, s writeBuffer(); - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/InStream.h =================================================================== --- tigervnc-1.8.0.orig/common/rdr/InStream.h +++ tigervnc-1.8.0/common/rdr/InStream.h @@ -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. virtual 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; } } Index: tigervnc-1.8.0/common/rdr/MemOutStream.h =================================================================== --- tigervnc-1.8.0.orig/common/rdr/MemOutStream.h +++ tigervnc-1.8.0/common/rdr/MemOutStream.h @@ -23,6 +23,7 @@ #ifndef __RDR_MEMOUTSTREAM_H__ #define __RDR_MEMOUTSTREAM_H__ +#include <rdr/Exception.h> #include <rdr/OutStream.h> namespace rdr { @@ -65,6 +66,9 @@ namespace rdr { if (len < (size_t)(end - start) * 2) len = (end - start) * 2; + if (len < (size_t)(end - start)) + throw Exception("Overflow in MemOutStream::overrun()"); + U8* newStart = new U8[len]; memcpy(newStart, start, ptr - start); ptr = newStart + (ptr - start); Index: tigervnc-1.8.0/common/rdr/OutStream.h =================================================================== --- tigervnc-1.8.0.orig/common/rdr/OutStream.h +++ tigervnc-1.8.0/common/rdr/OutStream.h @@ -46,12 +46,15 @@ namespace rdr { inline size_t check(size_t itemSize, size_t nItems=1) { - if (ptr + itemSize * nItems > end) { - if (ptr + itemSize > end) - return overrun(itemSize, nItems); + size_t nAvail; + + if (itemSize > (size_t)(end - ptr)) + return overrun(itemSize, nItems); + + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; - nItems = (end - ptr) / itemSize; - } return nItems; } @@ -91,13 +94,12 @@ namespace rdr { // writeBytes() writes an exact number of bytes. virtual void writeBytes(const void* data, size_t length) { - const U8* dataPtr = (const U8*)data; - const U8* dataEnd = dataPtr + length; - while (dataPtr < dataEnd) { - size_t n = check(1, dataEnd - dataPtr); - memcpy(ptr, dataPtr, n); + while (length > 0) { + size_t n = check(1, length); + memcpy(ptr, data, n); ptr += n; - dataPtr += n; + data = (U8*)data + n; + length -= n; } } Index: tigervnc-1.8.0/common/rdr/RandomStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/RandomStream.cxx +++ tigervnc-1.8.0/common/rdr/RandomStream.cxx @@ -123,8 +123,10 @@ size_t RandomStream::overrun(size_t item *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/TLSInStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/TLSInStream.cxx +++ tigervnc-1.8.0/common/rdr/TLSInStream.cxx @@ -43,7 +43,7 @@ ssize_t TLSInStream::pull(gnutls_transpo return -1; } - if (in->getend() - in->getptr() < (ptrdiff_t)size) + if ((size_t)(in->getend() - in->getptr()) < size) size = in->getend() - in->getptr(); in->readBytes(data, size); @@ -92,15 +92,17 @@ size_t TLSInStream::overrun(size_t itemS end -= ptr - start; ptr = start; - while (end < start + itemSize) { + while ((size_t)(end - start) < itemSize) { size_t n = readTLS((U8*) end, start + bufSize - end, wait); if (!wait && n == 0) return 0; end += n; } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/TLSOutStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/TLSOutStream.cxx +++ tigervnc-1.8.0/common/rdr/TLSOutStream.cxx @@ -100,8 +100,10 @@ size_t TLSOutStream::overrun(size_t item flush(); - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/ZlibInStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/ZlibInStream.cxx +++ tigervnc-1.8.0/common/rdr/ZlibInStream.cxx @@ -113,8 +113,10 @@ size_t ZlibInStream::overrun(size_t item return 0; } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } Index: tigervnc-1.8.0/common/rdr/ZlibOutStream.cxx =================================================================== --- tigervnc-1.8.0.orig/common/rdr/ZlibOutStream.cxx +++ tigervnc-1.8.0/common/rdr/ZlibOutStream.cxx @@ -127,8 +127,10 @@ size_t ZlibOutStream::overrun(size_t ite } } - if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor