Version in base suite: 1.9.0+dfsg-3 Base version: tigervnc_1.9.0+dfsg-3 Target version: tigervnc_1.9.0+dfsg-3+deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/tigervnc/tigervnc_1.9.0+dfsg-3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/t/tigervnc/tigervnc_1.9.0+dfsg-3+deb10u1.dsc changelog | 8 patches/CVE-2019-15691.patch | 116 +++ patches/CVE-2019-15692.patch | 458 ++++++++++++++ patches/CVE-2019-15693.patch | 75 ++ patches/CVE-2019-15694.patch | 1370 +++++++++++++++++++++++++++++++++++++++++++ patches/CVE-2019-15695.patch | 32 + patches/series | 5 7 files changed, 2064 insertions(+) diff -Nru tigervnc-1.9.0+dfsg/debian/changelog tigervnc-1.9.0+dfsg/debian/changelog --- tigervnc-1.9.0+dfsg/debian/changelog 2018-12-01 21:51:29.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/changelog 2020-01-23 18:03:00.000000000 +0000 @@ -1,3 +1,11 @@ +tigervnc (1.9.0+dfsg-3+deb10u1) buster; urgency=high + + [ Joachim Falk ] + * Fix CVE-2019-15691, CVE-2019-15692, CVE-2019-15693, CVE-2019-15694, and + CVE-2019-15695 (Closes: #947428) + + -- Joachim Falk Thu, 23 Jan 2020 19:03:00 +0100 + tigervnc (1.9.0+dfsg-3) unstable; urgency=medium [ Joachim Falk ] diff -Nru tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15691.patch tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15691.patch --- tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15691.patch 1970-01-01 00:00:00.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15691.patch 2020-01-23 18:02:50.000000000 +0000 @@ -0,0 +1,116 @@ +From d61a767d6842b530ffb532ddd5a3d233119aad40 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 10 Sep 2019 11:05:48 +0200 +Subject: [PATCH] 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 +--- + common/rdr/ZlibInStream.cxx | 13 +++++++------ + common/rdr/ZlibInStream.h | 2 +- + common/rfb/CMsgReader.cxx | 3 ++- + common/rfb/SMsgReader.cxx | 3 ++- + common/rfb/TightDecoder.cxx | 3 ++- + common/rfb/zrleDecode.h | 3 ++- + 6 files changed, 16 insertions(+), 11 deletions(-) + +Index: pkg-tigervnc/common/rdr/ZlibInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibInStream.cxx ++++ pkg-tigervnc/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, + { + 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, + + 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; + +Index: pkg-tigervnc/common/rdr/ZlibInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibInStream.h ++++ pkg-tigervnc/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(); + +Index: pkg-tigervnc/common/rfb/TightDecoder.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/TightDecoder.cxx ++++ pkg-tigervnc/common/rfb/TightDecoder.cxx +@@ -340,7 +340,8 @@ void TightDecoder::decodeRect(const Rect + + zis[streamId].readBytes(netbuf, dataSize); + +- zis[streamId].removeUnderlying(); ++ zis[streamId].flushUnderlying(); ++ zis[streamId].setUnderlying(NULL, 0); + delete ms; + + bufptr = netbuf; +Index: pkg-tigervnc/common/rfb/zrleDecode.h +=================================================================== +--- pkg-tigervnc.orig/common/rfb/zrleDecode.h ++++ pkg-tigervnc/common/rfb/zrleDecode.h +@@ -178,7 +178,8 @@ void ZRLE_DECODE (const Rect& r, rdr::In + } + } + +- zis->removeUnderlying(); ++ zis->flushUnderlying(); ++ zis->setUnderlying(NULL, 0); + } + + #undef ZRLE_DECODE diff -Nru tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15692.patch tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15692.patch --- tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15692.patch 1970-01-01 00:00:00.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15692.patch 2020-01-23 18:02:50.000000000 +0000 @@ -0,0 +1,458 @@ +From 996356b6c65ca165ee1ea46a571c32a1dc3c3821 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 10 Sep 2019 15:21:03 +0200 +Subject: [PATCH] Restrict PixelBuffer dimensions to safe values + +We do a lot of calculations based on pixel coordinates and we need +to make sure they do not overflow. Restrict the maximum dimensions +we support rather than try to switch over all calculations to use +64 bit integers. + +This prevents attackers from injecting code by specifying a +huge framebuffer size and relying on the values overflowing to +access invalid areas of the heap. + +This primarily affects the client which gets both the screen +dimensions and the pixel contents from the remote side. But the +server might also be affected as a client can adjust the screen +dimensions, as can applications inside the session. + +Issue found by Pavel Cheremushkin from Kaspersky Lab. +--- + common/rfb/PixelBuffer.cxx | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +Index: pkg-tigervnc/common/rfb/PixelBuffer.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/PixelBuffer.cxx ++++ pkg-tigervnc/common/rfb/PixelBuffer.cxx +@@ -31,11 +31,22 @@ using namespace rdr; + + static LogWriter vlog("PixelBuffer"); + ++// We do a lot of byte offset calculations that assume the result fits ++// inside a signed 32 bit integer. Limit the maximum size of pixel ++// buffers so that these calculations never overflow. ++ ++const int maxPixelBufferWidth = 16384; ++const int maxPixelBufferHeight = 16384; ++const int maxPixelBufferStride = 16384; ++ + + // -=- Generic pixel buffer class + + PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h) +- : format(pf), width_(w), height_(h) {} ++ : format(pf), width_(0), height_(0) ++{ ++ setSize(w, h); ++} + PixelBuffer::PixelBuffer() : width_(0), height_(0) {} + + PixelBuffer::~PixelBuffer() {} +@@ -100,6 +111,17 @@ void PixelBuffer::getImage(const PixelFo + stride, srcStride); + } + ++void PixelBuffer::setSize(int width, int height) ++{ ++ if ((width < 0) || (width > maxPixelBufferWidth)) ++ throw rfb::Exception("Invalid PixelBuffer width of %d pixels requested", width); ++ if ((height < 0) || (height > maxPixelBufferHeight)) ++ throw rfb::Exception("Invalid PixelBuffer height of %d pixels requested", height); ++ ++ width_ = width; ++ height_ = height; ++} ++ + // -=- Modifiable generic pixel buffer class + + ModifiablePixelBuffer::ModifiablePixelBuffer(const PixelFormat& pf, +@@ -124,7 +146,7 @@ void ModifiablePixelBuffer::fillRect(con + + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", +- r.width(), r.height(), r.tl.x, r.tl.y, width_, height_); ++ r.width(), r.height(), r.tl.x, r.tl.y, width(), height()); + + w = r.width(); + h = r.height(); +@@ -175,7 +197,7 @@ void ModifiablePixelBuffer::imageRect(co + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", + r.width(), r.height(), +- r.tl.x, r.tl.y, width_, height_); ++ r.tl.x, r.tl.y, width(), height()); + + bytesPerPixel = getPF().bpp/8; + +@@ -213,13 +235,13 @@ void ModifiablePixelBuffer::copyRect(con + if (!drect.enclosed_by(getRect())) + throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", + drect.width(), drect.height(), +- drect.tl.x, drect.tl.y, width_, height_); ++ drect.tl.x, drect.tl.y, width(), height()); + + srect = drect.translate(move_by_delta.negate()); + if (!srect.enclosed_by(getRect())) + throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d", + srect.width(), srect.height(), +- srect.tl.x, srect.tl.y, width_, height_); ++ srect.tl.x, srect.tl.y, width(), height()); + + srcData = getBuffer(srect, &srcStride); + dstData = getBufferRW(drect, &dstStride); +@@ -272,7 +294,7 @@ void ModifiablePixelBuffer::imageRect(co + if (!dest.enclosed_by(getRect())) + throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", + dest.width(), dest.height(), +- dest.tl.x, dest.tl.y, width_, height_); ++ dest.tl.x, dest.tl.y, width(), height()); + + if (stride == 0) + stride = dest.width(); +@@ -301,7 +323,7 @@ rdr::U8* FullFramePixelBuffer::getBuffer + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d", + r.width(), r.height(), +- r.tl.x, r.tl.y, width_, height_); ++ r.tl.x, r.tl.y, width(), height()); + + *stride_ = stride; + return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8]; +@@ -316,55 +338,76 @@ const rdr::U8* FullFramePixelBuffer::get + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d", + r.width(), r.height(), +- r.tl.x, r.tl.y, width_, height_); ++ r.tl.x, r.tl.y, width(), height()); + + *stride_ = stride; + return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8]; + } + ++void FullFramePixelBuffer::setBuffer(int width, int height, ++ rdr::U8* data_, int stride_) ++{ ++ if ((width < 0) || (width > maxPixelBufferWidth)) ++ throw rfb::Exception("Invalid PixelBuffer width of %d pixels requested", width); ++ if ((height < 0) || (height > maxPixelBufferHeight)) ++ throw rfb::Exception("Invalid PixelBuffer height of %d pixels requested", height); ++ if ((stride_ < 0) || (stride_ > maxPixelBufferStride) || (stride_ < width)) ++ throw rfb::Exception("Invalid PixelBuffer stride of %d pixels requested", stride_); ++ if ((width != 0) && (height != 0) && (data_ == NULL)) ++ throw rfb::Exception("PixelBuffer requested without a valid memory area"); ++ ++ ModifiablePixelBuffer::setSize(width, height); ++ stride = stride_; ++ data = data_; ++} ++ ++void FullFramePixelBuffer::setSize(int w, int h) ++{ ++ // setBuffer() should be used ++ throw rfb::Exception("Invalid call to FullFramePixelBuffer::setSize()"); ++} ++ + // -=- Managed pixel buffer class + // Automatically allocates enough space for the specified format & area + + ManagedPixelBuffer::ManagedPixelBuffer() +- : datasize(0) ++ : data_(NULL), datasize(0) + { +- checkDataSize(); + }; + + ManagedPixelBuffer::ManagedPixelBuffer(const PixelFormat& pf, int w, int h) +- : FullFramePixelBuffer(pf, w, h, NULL, w), datasize(0) ++ : FullFramePixelBuffer(pf, 0, 0, NULL, 0), data_(NULL), datasize(0) + { +- checkDataSize(); ++ setSize(w, h); + }; + + ManagedPixelBuffer::~ManagedPixelBuffer() { +- if (data) delete [] data; ++ if (data_) delete [] data_; + }; + + + void + ManagedPixelBuffer::setPF(const PixelFormat &pf) { +- format = pf; checkDataSize(); ++ format = pf; setSize(width(), height()); + }; + void + ManagedPixelBuffer::setSize(int w, int h) { +- width_ = w; height_ = h; stride = w; checkDataSize(); +-}; ++ unsigned long new_datasize = w * h * (format.bpp/8); + +- +-inline void +-ManagedPixelBuffer::checkDataSize() { +- unsigned long new_datasize = width_ * height_ * (format.bpp/8); ++ new_datasize = w * h * (format.bpp/8); + if (datasize < new_datasize) { +- if (data) { +- delete [] data; +- datasize = 0; data = 0; ++ if (data_) { ++ delete [] data_; ++ data_ = NULL; ++ datasize = 0; + } + if (new_datasize) { +- data = new U8[new_datasize]; +- if (!data) ++ data_ = new U8[new_datasize]; ++ if (!data_) + throw Exception("rfb::ManagedPixelBuffer unable to allocate buffer"); + datasize = new_datasize; + } + } ++ ++ setBuffer(w, h, data_, w); + }; +Index: pkg-tigervnc/common/rfb/Cursor.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/Cursor.cxx ++++ pkg-tigervnc/common/rfb/Cursor.cxx +@@ -271,8 +271,7 @@ void RenderedCursor::update(PixelBuffer* + assert(cursor); + + format = framebuffer->getPF(); +- width_ = framebuffer->width(); +- height_ = framebuffer->height(); ++ setSize(framebuffer->width(), framebuffer->height()); + + rawOffset = pos.subtract(cursor->hotspot()); + clippedRect = Rect(0, 0, cursor->width(), cursor->height()) +Index: pkg-tigervnc/common/rfb/PixelBuffer.h +=================================================================== +--- pkg-tigervnc.orig/common/rfb/PixelBuffer.h ++++ pkg-tigervnc/common/rfb/PixelBuffer.h +@@ -90,7 +90,10 @@ namespace rfb { + + protected: + PixelBuffer(); ++ virtual void setSize(int width, int height); ++ + PixelFormat format; ++ private: + int width_, height_; + }; + +@@ -154,7 +157,12 @@ namespace rfb { + + protected: + FullFramePixelBuffer(); ++ virtual void setBuffer(int width, int height, rdr::U8* data, int stride); ++ ++ private: ++ virtual void setSize(int w, int h); + ++ private: + rdr::U8* data; + int stride; + }; +@@ -173,11 +181,11 @@ namespace rfb { + virtual void setSize(int w, int h); + + // Return the total number of bytes of pixel data in the buffer +- int dataLen() const { return width_ * height_ * (format.bpp/8); } ++ int dataLen() const { return width() * height() * (format.bpp/8); } + +- protected: ++ private: ++ rdr::U8* data_; // Mirrors FullFramePixelBuffer::data + unsigned long datasize; +- void checkDataSize(); + }; + + }; +Index: pkg-tigervnc/common/rfb/EncodeManager.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/EncodeManager.cxx ++++ pkg-tigervnc/common/rfb/EncodeManager.cxx +@@ -979,11 +979,8 @@ void EncodeManager::OffsetPixelBuffer::u + int stride_) + { + format = pf; +- width_ = width; +- height_ = height; + // Forced cast. We never write anything though, so it should be safe. +- data = (rdr::U8*)data_; +- stride = stride_; ++ setBuffer(width, height, (rdr::U8*)data_, stride_); + } + + // Preprocessor generated, optimised methods +Index: pkg-tigervnc/unix/x0vncserver/XPixelBuffer.cxx +=================================================================== +--- pkg-tigervnc.orig/unix/x0vncserver/XPixelBuffer.cxx ++++ pkg-tigervnc/unix/x0vncserver/XPixelBuffer.cxx +@@ -50,13 +50,10 @@ XPixelBuffer::XPixelBuffer(Display *dpy, + ffs(m_image->xim->blue_mask) - 1); + + // Set up the remaining data of the parent class. +- width_ = rect.width(); +- height_ = rect.height(); +- data = (rdr::U8 *)m_image->xim->data; +- ++ setBuffer(rect.width(), rect.height(), (rdr::U8 *)m_image->xim->data, + // Calculate the distance in pixels between two subsequent scan + // lines of the framebuffer. This may differ from image width. +- stride = m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel; ++ m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel); + + // Get initial screen image from the X display. + m_image->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop); +Index: pkg-tigervnc/vncviewer/PlatformPixelBuffer.cxx +=================================================================== +--- pkg-tigervnc.orig/vncviewer/PlatformPixelBuffer.cxx ++++ pkg-tigervnc/vncviewer/PlatformPixelBuffer.cxx +@@ -36,14 +36,14 @@ static rfb::LogWriter vlog("PlatformPixe + PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : + FullFramePixelBuffer(rfb::PixelFormat(32, 24, false, true, + 255, 255, 255, 16, 8, 0), +- width, height, 0, stride), ++ 0, 0, NULL, 0), + Surface(width, height) + #if !defined(WIN32) && !defined(__APPLE__) + , shminfo(NULL), xim(NULL) + #endif + { + #if !defined(WIN32) && !defined(__APPLE__) +- if (!setupShm()) { ++ if (!setupShm(width, height)) { + xim = XCreateImage(fl_display, CopyFromParent, 32, + ZPixmap, 0, 0, width, height, 32, 0); + if (!xim) +@@ -65,11 +65,10 @@ PlatformPixelBuffer::PlatformPixelBuffer + vlog.debug("Using standard XImage"); + } + +- data = (rdr::U8*)xim->data; +- stride = xim->bytes_per_line / (getPF().bpp/8); ++ setBuffer(width, height, (rdr::U8*)xim->data, ++ xim->bytes_per_line / (getPF().bpp/8)); + #else +- FullFramePixelBuffer::data = (rdr::U8*)Surface::data; +- stride = width; ++ setBuffer(width, height, (rdr::U8*)Surface::data, width); + #endif + } + +@@ -140,7 +139,7 @@ static int XShmAttachErrorHandler(Displa + return 0; + } + +-bool PlatformPixelBuffer::setupShm() ++bool PlatformPixelBuffer::setupShm(int width, int height) + { + int major, minor; + Bool pixmaps; +@@ -157,7 +156,7 @@ bool PlatformPixelBuffer::setupShm() + shminfo = new XShmSegmentInfo; + + xim = XShmCreateImage(fl_display, CopyFromParent, 32, +- ZPixmap, 0, shminfo, width(), height()); ++ ZPixmap, 0, shminfo, width, height); + if (!xim) + goto free_shminfo; + +Index: pkg-tigervnc/vncviewer/PlatformPixelBuffer.h +=================================================================== +--- pkg-tigervnc.orig/vncviewer/PlatformPixelBuffer.h ++++ pkg-tigervnc/vncviewer/PlatformPixelBuffer.h +@@ -53,7 +53,7 @@ protected: + + #if !defined(WIN32) && !defined(__APPLE__) + protected: +- bool setupShm(); ++ bool setupShm(int width, int height); + + protected: + XShmSegmentInfo *shminfo; +Index: pkg-tigervnc/unix/xserver/hw/vnc/XserverDesktop.cc +=================================================================== +--- pkg-tigervnc.orig/unix/xserver/hw/vnc/XserverDesktop.cc ++++ pkg-tigervnc/unix/xserver/hw/vnc/XserverDesktop.cc +@@ -115,7 +115,7 @@ XserverDesktop::XserverDesktop(int scree + : screenIndex(screenIndex_), + server(0), httpServer(0), + listeners(listeners_), httpListeners(httpListeners_), +- directFbptr(true), ++ shadowFramebuffer(NULL), + queryConnectId(0), queryConnectTimer(this) + { + format = pf; +@@ -148,12 +148,12 @@ XserverDesktop::~XserverDesktop() + listeners.pop_back(); + } + while (!httpListeners.empty()) { +- vncRemoveNotifyFd(listeners.back()->getFd()); ++ vncRemoveNotifyFd(httpListeners.back()->getFd()); + delete httpListeners.back(); + httpListeners.pop_back(); + } +- if (!directFbptr) +- delete [] data; ++ if (shadowFramebuffer) ++ delete [] shadowFramebuffer; + delete httpServer; + delete server; + } +@@ -172,22 +172,18 @@ void XserverDesktop::setFramebuffer(int + { + ScreenSet layout; + +- width_ = w; +- height_ = h; +- +- if (!directFbptr) { +- delete [] data; +- directFbptr = true; ++ if (shadowFramebuffer) { ++ delete [] shadowFramebuffer; ++ shadowFramebuffer = NULL; + } + + if (!fbptr) { +- fbptr = new rdr::U8[w * h * (format.bpp/8)]; ++ shadowFramebuffer = new rdr::U8[w * h * (format.bpp/8)]; ++ fbptr = shadowFramebuffer; + stride_ = w; +- directFbptr = false; + } + +- data = (rdr::U8*)fbptr; +- stride = stride_; ++ setBuffer(w, h, (rdr::U8*)fbptr, stride_); + + vncSetGlueContext(screenIndex); + layout = ::computeScreenLayout(&outputIdMap); +@@ -569,7 +565,7 @@ unsigned int XserverDesktop::setScreenLa + + void XserverDesktop::grabRegion(const rfb::Region& region) + { +- if (directFbptr) ++ if (shadowFramebuffer == NULL) + return; + + std::vector rects; +Index: pkg-tigervnc/unix/xserver/hw/vnc/XserverDesktop.h +=================================================================== +--- pkg-tigervnc.orig/unix/xserver/hw/vnc/XserverDesktop.h ++++ pkg-tigervnc/unix/xserver/hw/vnc/XserverDesktop.h +@@ -124,7 +124,7 @@ private: + rfb::HTTPServer* httpServer; + std::list listeners; + std::list httpListeners; +- bool directFbptr; ++ rdr::U8* shadowFramebuffer; + + uint32_t queryConnectId; + network::Socket* queryConnectSocket; diff -Nru tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15693.patch tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15693.patch --- tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15693.patch 1970-01-01 00:00:00.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15693.patch 2020-01-18 23:56:00.000000000 +0000 @@ -0,0 +1,75 @@ +From b4ada8d0c6dac98c8b91fc64d112569a8ae5fb95 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 10 Sep 2019 15:36:42 +0200 +Subject: [PATCH] Handle empty Tight gradient rects + +We always assumed there would be one pixel per row so a rect with +a zero width would result in us writing to unknown memory. + +This could theoretically be used by a malicious server to inject +code in to the viewer process. + +Issue found by Pavel Cheremushkin from Kaspersky Lab. +--- + common/rfb/tightDecode.h | 37 +++++++++++++++++++++---------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +Index: pkg-tigervnc/common/rfb/tightDecode.h +=================================================================== +--- pkg-tigervnc.orig/common/rfb/tightDecode.h ++++ pkg-tigervnc/common/rfb/tightDecode.h +@@ -56,15 +56,17 @@ TightDecoder::FilterGradient24(const rdr + int rectWidth = r.width(); + + for (y = 0; y < rectHeight; y++) { +- /* First pixel in a row */ +- for (c = 0; c < 3; c++) { +- pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c]; +- thisRow[c] = pix[c]; +- } +- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); ++ for (x = 0; x < rectWidth; x++) { ++ /* First pixel in a row */ ++ if (x == 0) { ++ for (c = 0; c < 3; c++) { ++ pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c]; ++ thisRow[c] = pix[c]; ++ } ++ pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); ++ continue; ++ } + +- /* Remaining pixels of a row */ +- for (x = 1; x < rectWidth; x++) { + for (c = 0; c < 3; c++) { + est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; + if (est[c] > 0xff) { +@@ -103,17 +105,20 @@ void TightDecoder::FilterGradient(const + int rectWidth = r.width(); + + for (y = 0; y < rectHeight; y++) { +- /* First pixel in a row */ +- pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1); +- for (c = 0; c < 3; c++) +- pix[c] += prevRow[c]; ++ for (x = 0; x < rectWidth; x++) { ++ /* First pixel in a row */ ++ if (x == 0) { ++ pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1); ++ for (c = 0; c < 3; c++) ++ pix[c] += prevRow[c]; + +- memcpy(thisRow, pix, sizeof(pix)); ++ memcpy(thisRow, pix, sizeof(pix)); + +- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); ++ pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); ++ ++ continue; ++ } + +- /* Remaining pixels of a row */ +- for (x = 1; x < rectWidth; x++) { + for (c = 0; c < 3; c++) { + est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; + if (est[c] > 255) { diff -Nru tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15694.patch tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15694.patch --- tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15694.patch 1970-01-01 00:00:00.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15694.patch 2020-01-23 18:02:50.000000000 +0000 @@ -0,0 +1,1370 @@ +From 0943c006c7d900dfc0281639e992791d6c567438 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Mon, 23 Sep 2019 11:00:17 +0200 +Subject: [PATCH] Use size_t for lengths in stream objects + +Provides safety against them accidentally becoming negative because +of bugs in the calculations. + +Also does the same to CharArray and friends as they were strongly +connection to the stream objects. +--- + common/rdr/FdInStream.cxx | 20 ++++++++++---------- + common/rdr/FdInStream.h | 17 +++++++++-------- + common/rdr/FdOutStream.cxx | 20 ++++++++++---------- + common/rdr/FdOutStream.h | 12 ++++++------ + common/rdr/FileInStream.cxx | 8 ++++---- + common/rdr/FileInStream.h | 4 ++-- + common/rdr/HexInStream.cxx | 20 ++++++++++---------- + common/rdr/HexInStream.h | 12 ++++++------ + common/rdr/HexOutStream.cxx | 20 ++++++++++---------- + common/rdr/HexOutStream.h | 12 ++++++------ + common/rdr/InStream.h | 16 ++++++++-------- + common/rdr/MemInStream.h | 8 ++++---- + common/rdr/MemOutStream.h | 12 ++++++------ + common/rdr/OutStream.h | 20 ++++++++++---------- + common/rdr/RandomStream.cxx | 14 +++++++------- + common/rdr/RandomStream.h | 6 +++--- + common/rdr/TLSInStream.cxx | 10 +++++----- + common/rdr/TLSInStream.h | 10 +++++----- + common/rdr/TLSOutStream.cxx | 10 +++++----- + common/rdr/TLSOutStream.h | 10 +++++----- + common/rdr/ZlibInStream.cxx | 16 ++++++++-------- + common/rdr/ZlibInStream.h | 14 +++++++------- + common/rdr/ZlibOutStream.cxx | 10 +++++----- + common/rdr/ZlibOutStream.h | 10 +++++----- + common/rfb/Configuration.cxx | 6 +++--- + common/rfb/Configuration.h | 13 +++++++------ + common/rfb/Password.cxx | 6 +++--- + common/rfb/Password.h | 6 +++--- + common/rfb/util.h | 2 +- + 29 files changed, 184 insertions(+), 182 deletions(-) + +Index: pkg-tigervnc/common/rdr/FdInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FdInStream.cxx ++++ pkg-tigervnc/common/rdr/FdInStream.cxx +@@ -56,7 +56,7 @@ using namespace rdr; + enum { DEFAULT_BUF_SIZE = 8192, + MIN_BULK_SIZE = 1024 }; + +-FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_, ++FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_, + bool closeWhenDone_) + : fd(fd_), closeWhenDone(closeWhenDone_), + timeoutms(timeoutms_), blockCallback(0), +@@ -67,7 +67,7 @@ FdInStream::FdInStream(int fd_, int time + } + + FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_, +- int bufSize_) ++ size_t bufSize_) + : fd(fd_), timeoutms(0), blockCallback(blockCallback_), + timing(false), timeWaitedIn100us(5), timedKbits(0), + bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) +@@ -92,12 +92,12 @@ void FdInStream::setBlockCallback(FdInSt + timeoutms = 0; + } + +-int FdInStream::pos() ++size_t FdInStream::pos() + { + return offset + ptr - start; + } + +-void FdInStream::readBytes(void* data, int length) ++void FdInStream::readBytes(void* data, size_t length) + { + if (length < MIN_BULK_SIZE) { + InStream::readBytes(data, length); +@@ -106,7 +106,7 @@ void FdInStream::readBytes(void* data, i + + U8* dataPtr = (U8*)data; + +- int n = end - ptr; ++ size_t n = end - ptr; + if (n > length) n = length; + + memcpy(dataPtr, ptr, n); +@@ -123,7 +123,7 @@ void FdInStream::readBytes(void* data, i + } + + +-int FdInStream::overrun(int itemSize, int nItems, bool wait) ++size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) + { + if (itemSize > bufSize) + throw Exception("FdInStream overrun: max itemSize exceeded"); +@@ -135,7 +135,7 @@ int FdInStream::overrun(int itemSize, in + end -= ptr - start; + ptr = start; + +- int bytes_to_read; ++ size_t bytes_to_read; + while (end < start + itemSize) { + bytes_to_read = start + bufSize - end; + if (!timing) { +@@ -147,12 +147,12 @@ int FdInStream::overrun(int itemSize, in + // bytes is ineffecient. + bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8)); + } +- int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait); ++ size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait); + if (n == 0) return 0; + end += n; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +@@ -171,7 +171,7 @@ int FdInStream::overrun(int itemSize, in + // returning EINTR. + // + +-int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait) ++size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait) + { + struct timeval before, after; + if (timing) +Index: pkg-tigervnc/common/rdr/FdInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FdInStream.h ++++ pkg-tigervnc/common/rdr/FdInStream.h +@@ -37,16 +37,17 @@ namespace rdr { + + public: + +- FdInStream(int fd, int timeoutms=-1, int bufSize=0, ++ FdInStream(int fd, int timeoutms=-1, size_t bufSize=0, + bool closeWhenDone_=false); +- FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0); ++ FdInStream(int fd, FdInStreamBlockCallback* blockCallback, ++ size_t bufSize=0); + virtual ~FdInStream(); + + void setTimeout(int timeoutms); + void setBlockCallback(FdInStreamBlockCallback* blockCallback); + int getFd() { return fd; } +- int pos(); +- void readBytes(void* data, int length); ++ size_t pos(); ++ void readBytes(void* data, size_t length); + + void startTiming(); + void stopTiming(); +@@ -54,10 +55,10 @@ namespace rdr { + unsigned int timeWaited() { return timeWaitedIn100us; } + + protected: +- int overrun(int itemSize, int nItems, bool wait); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait); + + private: +- int readWithTimeoutOrCallback(void* buf, int len, bool wait=true); ++ size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true); + + int fd; + bool closeWhenDone; +@@ -68,8 +69,8 @@ namespace rdr { + unsigned int timeWaitedIn100us; + unsigned int timedKbits; + +- int bufSize; +- int offset; ++ size_t bufSize; ++ size_t offset; + U8* start; + }; + +Index: pkg-tigervnc/common/rdr/FdOutStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FdOutStream.cxx ++++ pkg-tigervnc/common/rdr/FdOutStream.cxx +@@ -51,7 +51,7 @@ using namespace rdr; + + enum { DEFAULT_BUF_SIZE = 16384 }; + +-FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_) ++FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_) + : fd(fd_), blocking(blocking_), timeoutms(timeoutms_), + bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) + { +@@ -79,7 +79,7 @@ void FdOutStream::setBlocking(bool block + blocking = blocking_; + } + +-int FdOutStream::length() ++size_t FdOutStream::length() + { + return offset + ptr - sentUpTo; + } +@@ -97,9 +97,9 @@ unsigned FdOutStream::getIdleTime() + void FdOutStream::flush() + { + while (sentUpTo < ptr) { +- int n = writeWithTimeout((const void*) sentUpTo, +- ptr - sentUpTo, +- blocking? timeoutms : 0); ++ size_t n = writeWithTimeout((const void*) sentUpTo, ++ ptr - sentUpTo, ++ blocking? timeoutms : 0); + + // Timeout? + if (n == 0) { +@@ -120,7 +120,7 @@ void FdOutStream::flush() + } + + +-int FdOutStream::overrun(int itemSize, int nItems) ++size_t FdOutStream::overrun(size_t itemSize, size_t nItems) + { + if (itemSize > bufSize) + throw Exception("FdOutStream overrun: max itemSize exceeded"); +@@ -129,10 +129,10 @@ int FdOutStream::overrun(int itemSize, i + flush(); + + // Still not enough space? +- if (itemSize > end - ptr) { ++ if (itemSize > (size_t)(end - ptr)) { + // Can we shuffle things around? + // (don't do this if it gains us less than 25%) +- if ((sentUpTo - start > bufSize / 4) && ++ if (((size_t)(sentUpTo - start) > bufSize / 4) && + (itemSize < bufSize - (ptr - sentUpTo))) { + memmove(start, sentUpTo, ptr - sentUpTo); + ptr = start + (ptr - sentUpTo); +@@ -150,7 +150,7 @@ int FdOutStream::overrun(int itemSize, i + } + + // Can we fit all the items asked for? +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +@@ -166,7 +166,7 @@ int FdOutStream::overrun(int itemSize, i + // select() and send() returning EINTR. + // + +-int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms) ++size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms) + { + int n; + +Index: pkg-tigervnc/common/rdr/FdOutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FdOutStream.h ++++ pkg-tigervnc/common/rdr/FdOutStream.h +@@ -34,7 +34,7 @@ namespace rdr { + + public: + +- FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0); ++ FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0); + virtual ~FdOutStream(); + + void setTimeout(int timeoutms); +@@ -42,20 +42,20 @@ namespace rdr { + int getFd() { return fd; } + + void flush(); +- int length(); ++ size_t length(); + + int bufferUsage(); + + unsigned getIdleTime(); + + private: +- int overrun(int itemSize, int nItems); +- int writeWithTimeout(const void* data, int length, int timeoutms); ++ size_t overrun(size_t itemSize, size_t nItems); ++ size_t writeWithTimeout(const void* data, size_t length, int timeoutms); + int fd; + bool blocking; + int timeoutms; +- int bufSize; +- int offset; ++ size_t bufSize; ++ size_t offset; + U8* start; + U8* sentUpTo; + struct timeval lastWrite; +Index: pkg-tigervnc/common/rdr/FileInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FileInStream.cxx ++++ pkg-tigervnc/common/rdr/FileInStream.cxx +@@ -48,7 +48,7 @@ void FileInStream::reset(void) { + ptr = end = b; + } + +-int FileInStream::pos() ++size_t FileInStream::pos() + { + if (!file) + throw Exception("File is not open"); +@@ -56,9 +56,9 @@ int FileInStream::pos() + return ftell(file) + ptr - b; + } + +-int FileInStream::overrun(int itemSize, int nItems, bool wait) ++size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) + { +- if (itemSize > (int)sizeof(b)) ++ if (itemSize > sizeof(b)) + throw Exception("FileInStream overrun: max itemSize exceeded"); + + if (end - ptr != 0) +@@ -80,7 +80,7 @@ int FileInStream::overrun(int itemSize, + end += b + sizeof(b) - end; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +Index: pkg-tigervnc/common/rdr/FileInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/FileInStream.h ++++ pkg-tigervnc/common/rdr/FileInStream.h +@@ -35,10 +35,10 @@ namespace rdr { + + void reset(void); + +- int pos(); ++ size_t pos(); + + protected: +- int overrun(int itemSize, int nItems, bool wait = true); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait = true); + + private: + U8 b[131072]; +Index: pkg-tigervnc/common/rdr/HexInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/HexInStream.cxx ++++ pkg-tigervnc/common/rdr/HexInStream.cxx +@@ -28,7 +28,7 @@ const int DEFAULT_BUF_LEN = 16384; + + static inline int min(int a, int b) {return a bufSize) + throw Exception("HexInStream overrun: max itemSize exceeded"); + +@@ -92,14 +92,14 @@ int HexInStream::overrun(int itemSize, i + ptr = start; + + while (end < ptr + itemSize) { +- int n = in_stream.check(2, 1, wait); ++ size_t n = in_stream.check(2, 1, wait); + if (n == 0) return 0; + const U8* iptr = in_stream.getptr(); + const U8* eptr = in_stream.getend(); +- int length = min((eptr - iptr)/2, start + bufSize - end); ++ size_t length = min((eptr - iptr)/2, start + bufSize - end); + + U8* optr = (U8*) end; +- for (int i=0; i end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +Index: pkg-tigervnc/common/rdr/HexInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/HexInStream.h ++++ pkg-tigervnc/common/rdr/HexInStream.h +@@ -26,21 +26,21 @@ namespace rdr { + class HexInStream : public InStream { + public: + +- HexInStream(InStream& is, int bufSize=0); ++ HexInStream(InStream& is, size_t bufSize=0); + virtual ~HexInStream(); + +- int pos(); ++ size_t pos(); + + static bool readHexAndShift(char c, int* v); +- static bool hexStrToBin(const char* s, char** data, int* length); ++ static bool hexStrToBin(const char* s, char** data, size_t* length); + + protected: +- int overrun(int itemSize, int nItems, bool wait); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait); + + private: +- int bufSize; ++ size_t bufSize; + U8* start; +- int offset; ++ size_t offset; + + InStream& in_stream; + }; +Index: pkg-tigervnc/common/rdr/HexOutStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/HexOutStream.cxx ++++ pkg-tigervnc/common/rdr/HexOutStream.cxx +@@ -23,9 +23,9 @@ using namespace rdr; + + const int DEFAULT_BUF_LEN = 16384; + +-static inline int min(int a, int b) {return a> 4) & 15); + buffer[i*2+1] = intToHex((data[i] & 15)); + if (!buffer[i*2] || !buffer[i*2+1]) { +@@ -70,9 +70,9 @@ HexOutStream::writeBuffer() { + out_stream.check(2); + U8* optr = out_stream.getptr(); + U8* oend = out_stream.getend(); +- int length = min(ptr-pos, (oend-optr)/2); ++ size_t length = min(ptr-pos, (oend-optr)/2); + +- for (int i=0; i> 4) & 0xf); + optr[i*2+1] = intToHex(pos[i] & 0xf); + } +@@ -84,7 +84,7 @@ HexOutStream::writeBuffer() { + ptr = start; + } + +-int HexOutStream::length() ++size_t HexOutStream::length() + { + return offset + ptr - start; + } +@@ -95,14 +95,14 @@ HexOutStream::flush() { + out_stream.flush(); + } + +-int +-HexOutStream::overrun(int itemSize, int nItems) { ++size_t ++HexOutStream::overrun(size_t itemSize, size_t nItems) { + if (itemSize > bufSize) + throw Exception("HexOutStream overrun: max itemSize exceeded"); + + writeBuffer(); + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +Index: pkg-tigervnc/common/rdr/HexOutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/HexOutStream.h ++++ pkg-tigervnc/common/rdr/HexOutStream.h +@@ -26,24 +26,24 @@ namespace rdr { + class HexOutStream : public OutStream { + public: + +- HexOutStream(OutStream& os, int buflen=0); ++ HexOutStream(OutStream& os, size_t buflen=0); + virtual ~HexOutStream(); + + void flush(); +- int length(); ++ size_t length(); + + static char intToHex(int i); +- static char* binToHexStr(const char* data, int length); ++ static char* binToHexStr(const char* data, size_t length); + + private: + void writeBuffer(); +- int overrun(int itemSize, int nItems); ++ size_t overrun(size_t itemSize, size_t nItems); + + OutStream& out_stream; + + U8* start; +- int offset; +- int bufSize; ++ size_t offset; ++ size_t bufSize; + }; + + } +Index: pkg-tigervnc/common/rdr/InStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/InStream.h ++++ pkg-tigervnc/common/rdr/InStream.h +@@ -41,7 +41,7 @@ namespace rdr { + // for the bytes, zero is returned if the bytes are not immediately + // available. + +- inline int check(int itemSize, int nItems=1, bool wait=true) ++ inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true) + { + if (ptr + itemSize * nItems > end) { + if (ptr + itemSize > end) +@@ -56,7 +56,7 @@ namespace rdr { + // be read without blocking. It returns true if this is the case, false + // otherwise. The length must be "small" (less than the buffer size). + +- inline bool checkNoWait(int length) { return check(length, 1, false)!=0; } ++ inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; } + + // readU/SN() methods read unsigned and signed N-bit integers. + +@@ -82,9 +82,9 @@ namespace rdr { + + static U32 maxStringLength; + +- inline void skip(int bytes) { ++ inline void skip(size_t bytes) { + while (bytes > 0) { +- int n = check(1, bytes); ++ size_t n = check(1, bytes); + ptr += n; + bytes -= n; + } +@@ -92,11 +92,11 @@ namespace rdr { + + // readBytes() reads an exact number of bytes. + +- void readBytes(void* data, int length) { ++ void readBytes(void* data, size_t length) { + U8* dataPtr = (U8*)data; + U8* dataEnd = dataPtr + length; + while (dataPtr < dataEnd) { +- int n = check(1, dataEnd - dataPtr); ++ size_t n = check(1, dataEnd - dataPtr); + memcpy(dataPtr, ptr, n); + ptr += n; + dataPtr += n; +@@ -114,7 +114,7 @@ namespace rdr { + + // pos() returns the position in the stream. + +- virtual int pos() = 0; ++ virtual size_t pos() = 0; + + // getptr(), getend() and setptr() are "dirty" methods which allow you to + // manipulate the buffer directly. This is useful for a stream which is a +@@ -133,7 +133,7 @@ namespace rdr { + // instead of blocking to wait for the bytes, zero is returned if the bytes + // are not immediately available. + +- virtual int overrun(int itemSize, int nItems, bool wait=true) = 0; ++ virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0; + + protected: + +Index: pkg-tigervnc/common/rdr/MemInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/MemInStream.h ++++ pkg-tigervnc/common/rdr/MemInStream.h +@@ -36,7 +36,7 @@ namespace rdr { + + public: + +- MemInStream(const void* data, int len, bool deleteWhenDone_=false) ++ MemInStream(const void* data, size_t len, bool deleteWhenDone_=false) + : start((const U8*)data), deleteWhenDone(deleteWhenDone_) + { + ptr = start; +@@ -48,12 +48,12 @@ namespace rdr { + delete [] start; + } + +- int pos() { return ptr - start; } +- void reposition(int pos) { ptr = start + pos; } ++ size_t pos() { return ptr - start; } ++ void reposition(size_t pos) { ptr = start + pos; } + + private: + +- int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); } ++ size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); } + const U8* start; + bool deleteWhenDone; + }; +Index: pkg-tigervnc/common/rdr/MemOutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/MemOutStream.h ++++ pkg-tigervnc/common/rdr/MemOutStream.h +@@ -40,16 +40,16 @@ namespace rdr { + delete [] start; + } + +- void writeBytes(const void* data, int length) { ++ void writeBytes(const void* data, size_t length) { + check(length); + memcpy(ptr, data, length); + ptr += length; + } + +- int length() { return ptr - start; } ++ size_t length() { return ptr - start; } + void clear() { ptr = start; }; + void clearAndZero() { memset(start, 0, ptr-start); clear(); } +- void reposition(int pos) { ptr = start + pos; } ++ void reposition(size_t pos) { ptr = start + pos; } + + // data() returns a pointer to the buffer. + +@@ -60,9 +60,9 @@ namespace rdr { + // overrun() either doubles the buffer or adds enough space for nItems of + // size itemSize bytes. + +- int overrun(int itemSize, int nItems) { +- int len = ptr - start + itemSize * nItems; +- if (len < (end - start) * 2) ++ size_t overrun(size_t itemSize, size_t nItems) { ++ size_t len = ptr - start + itemSize * nItems; ++ if (len < (size_t)(end - start) * 2) + len = (end - start) * 2; + + U8* newStart = new U8[len]; +Index: pkg-tigervnc/common/rdr/OutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/OutStream.h ++++ pkg-tigervnc/common/rdr/OutStream.h +@@ -44,7 +44,7 @@ namespace rdr { + // itemSize bytes. Returns the number of items which fit (up to a maximum + // of nItems). + +- inline int check(int itemSize, int nItems=1) ++ inline size_t check(size_t itemSize, size_t nItems=1) + { + if (ptr + itemSize * nItems > end) { + if (ptr + itemSize > end) +@@ -76,13 +76,13 @@ namespace rdr { + writeBytes(str, len); + } + +- inline void pad(int bytes) { ++ inline void pad(size_t bytes) { + while (bytes-- > 0) writeU8(0); + } + +- inline void skip(int bytes) { ++ inline void skip(size_t bytes) { + while (bytes > 0) { +- int n = check(1, bytes); ++ size_t n = check(1, bytes); + ptr += n; + bytes -= n; + } +@@ -90,11 +90,11 @@ namespace rdr { + + // writeBytes() writes an exact number of bytes. + +- void writeBytes(const void* data, int length) { ++ void writeBytes(const void* data, size_t length) { + const U8* dataPtr = (const U8*)data; + const U8* dataEnd = dataPtr + length; + while (dataPtr < dataEnd) { +- int n = check(1, dataEnd - dataPtr); ++ size_t n = check(1, dataEnd - dataPtr); + memcpy(ptr, dataPtr, n); + ptr += n; + dataPtr += n; +@@ -103,9 +103,9 @@ namespace rdr { + + // copyBytes() efficiently transfers data between streams + +- void copyBytes(InStream* is, int length) { ++ void copyBytes(InStream* is, size_t length) { + while (length > 0) { +- int n = check(1, length); ++ size_t n = check(1, length); + is->readBytes(ptr, n); + ptr += n; + length -= n; +@@ -124,7 +124,7 @@ namespace rdr { + + // length() returns the length of the stream. + +- virtual int length() = 0; ++ virtual size_t length() = 0; + + // flush() requests that the stream be flushed. + +@@ -145,7 +145,7 @@ namespace rdr { + // the number of items which fit (up to a maximum of nItems). itemSize is + // supposed to be "small" (a few bytes). + +- virtual int overrun(int itemSize, int nItems) = 0; ++ virtual size_t overrun(size_t itemSize, size_t nItems) = 0; + + protected: + +Index: pkg-tigervnc/common/rdr/RandomStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/RandomStream.cxx ++++ pkg-tigervnc/common/rdr/RandomStream.cxx +@@ -32,7 +32,7 @@ + + using namespace rdr; + +-const int DEFAULT_BUF_LEN = 256; ++const size_t DEFAULT_BUF_LEN = 256; + + unsigned int RandomStream::seed; + +@@ -83,11 +83,11 @@ RandomStream::~RandomStream() { + #endif + } + +-int RandomStream::pos() { ++size_t RandomStream::pos() { + return offset + ptr - start; + } + +-int RandomStream::overrun(int itemSize, int nItems, bool wait) { ++size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) { + if (itemSize > DEFAULT_BUF_LEN) + throw Exception("RandomStream overrun: max itemSize exceeded"); + +@@ -98,7 +98,7 @@ int RandomStream::overrun(int itemSize, + offset += ptr - start; + ptr = start; + +- int length = start + DEFAULT_BUF_LEN - end; ++ size_t length = start + DEFAULT_BUF_LEN - end; + + #ifdef RFB_HAVE_WINCRYPT + if (provider) { +@@ -109,7 +109,7 @@ int RandomStream::overrun(int itemSize, + #else + #ifndef WIN32 + if (fp) { +- int n = fread((U8*)end, length, 1, fp); ++ size_t n = fread((U8*)end, length, 1, fp); + if (n != 1) + throw rdr::SystemException("reading /dev/urandom or /dev/random failed", + errno); +@@ -119,11 +119,11 @@ int RandomStream::overrun(int itemSize, + { + #endif + #endif +- for (int i=0; i end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +Index: pkg-tigervnc/common/rdr/RandomStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/RandomStream.h ++++ pkg-tigervnc/common/rdr/RandomStream.h +@@ -39,14 +39,14 @@ namespace rdr { + RandomStream(); + virtual ~RandomStream(); + +- int pos(); ++ size_t pos(); + + protected: +- int overrun(int itemSize, int nItems, bool wait); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait); + + private: + U8* start; +- int offset; ++ size_t offset; + + static unsigned int seed; + #ifdef RFB_HAVE_WINCRYPT +Index: pkg-tigervnc/common/rdr/TLSInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/TLSInStream.cxx ++++ pkg-tigervnc/common/rdr/TLSInStream.cxx +@@ -75,12 +75,12 @@ TLSInStream::~TLSInStream() + delete[] start; + } + +-int TLSInStream::pos() ++size_t TLSInStream::pos() + { + return offset + ptr - start; + } + +-int TLSInStream::overrun(int itemSize, int nItems, bool wait) ++size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait) + { + if (itemSize > bufSize) + throw Exception("TLSInStream overrun: max itemSize exceeded"); +@@ -93,19 +93,19 @@ int TLSInStream::overrun(int itemSize, i + ptr = start; + + while (end < start + itemSize) { +- int n = readTLS((U8*) end, start + bufSize - end, wait); ++ size_t n = readTLS((U8*) end, start + bufSize - end, wait); + if (!wait && n == 0) + return 0; + end += n; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; + } + +-int TLSInStream::readTLS(U8* buf, int len, bool wait) ++size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait) + { + int n; + +Index: pkg-tigervnc/common/rdr/TLSInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/TLSInStream.h ++++ pkg-tigervnc/common/rdr/TLSInStream.h +@@ -36,17 +36,17 @@ namespace rdr { + TLSInStream(InStream* in, gnutls_session_t session); + virtual ~TLSInStream(); + +- int pos(); ++ size_t pos(); + + private: +- int overrun(int itemSize, int nItems, bool wait); +- int readTLS(U8* buf, int len, bool wait); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait); ++ size_t readTLS(U8* buf, size_t len, bool wait); + static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size); + + gnutls_session_t session; + InStream* in; +- int bufSize; +- int offset; ++ size_t bufSize; ++ size_t offset; + U8* start; + }; + }; +Index: pkg-tigervnc/common/rdr/TLSOutStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/TLSOutStream.cxx ++++ pkg-tigervnc/common/rdr/TLSOutStream.cxx +@@ -75,7 +75,7 @@ TLSOutStream::~TLSOutStream() + delete [] start; + } + +-int TLSOutStream::length() ++size_t TLSOutStream::length() + { + return offset + ptr - start; + } +@@ -84,7 +84,7 @@ void TLSOutStream::flush() + { + U8* sentUpTo = start; + while (sentUpTo < ptr) { +- int n = writeTLS(sentUpTo, ptr - sentUpTo); ++ size_t n = writeTLS(sentUpTo, ptr - sentUpTo); + sentUpTo += n; + offset += n; + } +@@ -93,20 +93,20 @@ void TLSOutStream::flush() + out->flush(); + } + +-int TLSOutStream::overrun(int itemSize, int nItems) ++size_t TLSOutStream::overrun(size_t itemSize, size_t nItems) + { + if (itemSize > bufSize) + throw Exception("TLSOutStream overrun: max itemSize exceeded"); + + flush(); + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; + } + +-int TLSOutStream::writeTLS(const U8* data, int length) ++size_t TLSOutStream::writeTLS(const U8* data, size_t length) + { + int n; + +Index: pkg-tigervnc/common/rdr/TLSOutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/TLSOutStream.h ++++ pkg-tigervnc/common/rdr/TLSOutStream.h +@@ -36,20 +36,20 @@ namespace rdr { + virtual ~TLSOutStream(); + + void flush(); +- int length(); ++ size_t length(); + + protected: +- int overrun(int itemSize, int nItems); ++ size_t overrun(size_t itemSize, size_t nItems); + + private: +- int writeTLS(const U8* data, int length); ++ size_t writeTLS(const U8* data, size_t length); + static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size); + + gnutls_session_t session; + OutStream* out; +- int bufSize; ++ size_t bufSize; + U8* start; +- int offset; ++ size_t offset; + }; + }; + +Index: pkg-tigervnc/common/rdr/ZlibInStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibInStream.cxx ++++ pkg-tigervnc/common/rdr/ZlibInStream.cxx +@@ -26,7 +26,7 @@ using namespace rdr; + + enum { DEFAULT_BUF_SIZE = 16384 }; + +-ZlibInStream::ZlibInStream(int bufSize_) ++ZlibInStream::ZlibInStream(size_t bufSize_) + : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0), + zs(NULL), bytesIn(0) + { +@@ -40,14 +40,14 @@ ZlibInStream::~ZlibInStream() + delete [] start; + } + +-void ZlibInStream::setUnderlying(InStream* is, int bytesIn_) ++void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_) + { + underlying = is; + bytesIn = bytesIn_; + ptr = end = start; + } + +-int ZlibInStream::pos() ++size_t ZlibInStream::pos() + { + return offset + ptr - start; + } +@@ -96,7 +96,7 @@ void ZlibInStream::deinit() + zs = NULL; + } + +-int ZlibInStream::overrun(int itemSize, int nItems, bool wait) ++size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait) + { + if (itemSize > bufSize) + throw Exception("ZlibInStream overrun: max itemSize exceeded"); +@@ -108,12 +108,12 @@ int ZlibInStream::overrun(int itemSize, + end -= ptr - start; + ptr = start; + +- while (end - ptr < itemSize) { ++ while ((size_t)(end - ptr) < itemSize) { + if (!decompress(wait)) + return 0; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +@@ -131,11 +131,11 @@ bool ZlibInStream::decompress(bool wait) + zs->next_out = (U8*)end; + zs->avail_out = start + bufSize - end; + +- int n = underlying->check(1, 1, wait); ++ size_t n = underlying->check(1, 1, wait); + if (n == 0) return false; + zs->next_in = (U8*)underlying->getptr(); + zs->avail_in = underlying->getend() - underlying->getptr(); +- if ((int)zs->avail_in > bytesIn) ++ if (zs->avail_in > bytesIn) + zs->avail_in = bytesIn; + + int rc = inflate(zs, Z_SYNC_FLUSH); +Index: pkg-tigervnc/common/rdr/ZlibInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibInStream.h ++++ pkg-tigervnc/common/rdr/ZlibInStream.h +@@ -34,12 +34,12 @@ namespace rdr { + + public: + +- ZlibInStream(int bufSize=0); ++ ZlibInStream(size_t bufSize=0); + virtual ~ZlibInStream(); + +- void setUnderlying(InStream* is, int bytesIn); ++ void setUnderlying(InStream* is, size_t bytesIn); + void flushUnderlying(); +- int pos(); ++ size_t pos(); + void reset(); + + private: +@@ -47,14 +47,14 @@ namespace rdr { + void init(); + void deinit(); + +- int overrun(int itemSize, int nItems, bool wait); ++ size_t overrun(size_t itemSize, size_t nItems, bool wait); + bool decompress(bool wait); + + InStream* underlying; +- int bufSize; +- int offset; ++ size_t bufSize; ++ size_t offset; + z_stream_s* zs; +- int bytesIn; ++ size_t bytesIn; + U8* start; + }; + +Index: pkg-tigervnc/common/rdr/ZlibOutStream.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibOutStream.cxx ++++ pkg-tigervnc/common/rdr/ZlibOutStream.cxx +@@ -30,7 +30,7 @@ using namespace rdr; + + enum { DEFAULT_BUF_SIZE = 16384 }; + +-ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel) ++ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel) + : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel), + bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) + { +@@ -72,7 +72,7 @@ void ZlibOutStream::setCompressionLevel( + newLevel = level; + } + +-int ZlibOutStream::length() ++size_t ZlibOutStream::length() + { + return offset + ptr - start; + } +@@ -95,7 +95,7 @@ void ZlibOutStream::flush() + ptr = start; + } + +-int ZlibOutStream::overrun(int itemSize, int nItems) ++size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) + { + #ifdef ZLIBOUT_DEBUG + fprintf(stderr,"zos overrun\n"); +@@ -106,7 +106,7 @@ int ZlibOutStream::overrun(int itemSize, + + checkCompressionLevel(); + +- while (end - ptr < itemSize) { ++ while ((size_t)(end - ptr) < itemSize) { + zs->next_in = start; + zs->avail_in = ptr - start; + +@@ -127,7 +127,7 @@ int ZlibOutStream::overrun(int itemSize, + } + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +Index: pkg-tigervnc/common/rdr/ZlibOutStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/ZlibOutStream.h ++++ pkg-tigervnc/common/rdr/ZlibOutStream.h +@@ -35,25 +35,25 @@ namespace rdr { + + public: + +- ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1); ++ ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1); + virtual ~ZlibOutStream(); + + void setUnderlying(OutStream* os); + void setCompressionLevel(int level=-1); + void flush(); +- int length(); ++ size_t length(); + + private: + +- int overrun(int itemSize, int nItems); ++ size_t overrun(size_t itemSize, size_t nItems); + void deflate(int flush); + void checkCompressionLevel(); + + OutStream* underlying; + int compressionLevel; + int newLevel; +- int bufSize; +- int offset; ++ size_t bufSize; ++ size_t offset; + z_stream_s* zs; + U8* start; + }; +Index: pkg-tigervnc/common/rfb/Configuration.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/Configuration.cxx ++++ pkg-tigervnc/common/rfb/Configuration.cxx +@@ -421,7 +421,7 @@ StringParameter::operator const char *() + // -=- BinaryParameter + + BinaryParameter::BinaryParameter(const char* name_, const char* desc_, +- const void* v, int l, ConfigurationObject co) ++ const void* v, size_t l, ConfigurationObject co) + : VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) { + if (l) { + value = new char[l]; +@@ -441,7 +441,7 @@ bool BinaryParameter::setParam(const cha + return rdr::HexInStream::hexStrToBin(v, &value, &length); + } + +-void BinaryParameter::setParam(const void* v, int len) { ++void BinaryParameter::setParam(const void* v, size_t len) { + LOCK_CONFIG; + if (immutable) return; + vlog.debug("set %s(Binary)", getName()); +@@ -462,7 +462,7 @@ char* BinaryParameter::getValueStr() con + return rdr::HexOutStream::binToHexStr(value, length); + } + +-void BinaryParameter::getData(void** data_, int* length_) const { ++void BinaryParameter::getData(void** data_, size_t* length_) const { + LOCK_CONFIG; + if (length_) *length_ = length; + if (data_) { +Index: pkg-tigervnc/common/rfb/Configuration.h +=================================================================== +--- pkg-tigervnc.orig/common/rfb/Configuration.h ++++ pkg-tigervnc/common/rfb/Configuration.h +@@ -256,24 +256,25 @@ namespace rfb { + + class BinaryParameter : public VoidParameter { + public: +- BinaryParameter(const char* name_, const char* desc_, const void* v, int l, +- ConfigurationObject co=ConfGlobal); ++ BinaryParameter(const char* name_, const char* desc_, ++ const void* v, size_t l, ++ ConfigurationObject co=ConfGlobal); + using VoidParameter::setParam; + virtual ~BinaryParameter(); + virtual bool setParam(const char* value); +- virtual void setParam(const void* v, int l); ++ virtual void setParam(const void* v, size_t l); + virtual char* getDefaultStr() const; + virtual char* getValueStr() const; + + // getData() will return length zero if there is no data + // NB: data may be set to zero, OR set to a zero-length buffer +- void getData(void** data, int* length) const; ++ void getData(void** data, size_t* length) const; + + protected: + char* value; +- int length; ++ size_t length; + char* def_value; +- int def_length; ++ size_t def_length; + }; + + // -=- ParameterIterator +Index: pkg-tigervnc/common/rfb/Password.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/Password.cxx ++++ pkg-tigervnc/common/rfb/Password.cxx +@@ -38,7 +38,7 @@ PlainPasswd::PlainPasswd() {} + PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { + } + +-PlainPasswd::PlainPasswd(int len) : CharArray(len) { ++PlainPasswd::PlainPasswd(size_t len) : CharArray(len) { + } + + PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { +@@ -63,11 +63,11 @@ void PlainPasswd::replaceBuf(char* b) { + ObfuscatedPasswd::ObfuscatedPasswd() : length(0) { + } + +-ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) { ++ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) { + } + + ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) { +- int l = strlen(plainPwd.buf), i; ++ size_t l = strlen(plainPwd.buf), i; + for (i=0; i<8; i++) + buf[i] = i end - ptr) +Index: pkg-tigervnc/common/rdr/SubstitutingInStream.h +=================================================================== +--- pkg-tigervnc.orig/common/rdr/SubstitutingInStream.h ++++ pkg-tigervnc/common/rdr/SubstitutingInStream.h +@@ -45,9 +45,9 @@ namespace rdr { + delete [] subst; + } + +- int pos() { return underlying->pos(); } ++ size_t pos() { return underlying->pos(); } + +- virtual int overrun(int itemSize, int nItems, bool wait=true) { ++ virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) { + if (itemSize != 1) + throw new rdr::Exception("SubstitutingInStream: itemSize must be 1"); + +@@ -85,7 +85,7 @@ namespace rdr { + if (!subst && dollar) end = dollar; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; diff -Nru tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15695.patch tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15695.patch --- tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15695.patch 1970-01-01 00:00:00.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/CVE-2019-15695.patch 2020-01-23 18:02:50.000000000 +0000 @@ -0,0 +1,32 @@ +From 05e28490873a861379c943bf616614b78b558b89 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Wed, 2 Oct 2019 16:06:08 +0200 +Subject: [PATCH] Handle pixel formats with odd shift values + +Our fast paths assume that each channel fits in to a separate byte. +That means the shift needs to be a multiple of 8. Start actually +checking this so that a client cannot trip us up and possibly cause +incorrect code execution. + +Issue found by Pavel Cheremushkin from Kaspersky Lab. +--- + common/rfb/PixelFormat.cxx | 6 ++++++ + 1 files changed, 12 insertions(+) + +Index: pkg-tigervnc/common/rfb/PixelFormat.cxx +=================================================================== +--- pkg-tigervnc.orig/common/rfb/PixelFormat.cxx ++++ pkg-tigervnc/common/rfb/PixelFormat.cxx +@@ -205,6 +205,12 @@ bool PixelFormat::is888(void) const + return false; + if (blueMax != 255) + return false; ++ if ((redShift & 0x7) != 0) ++ return false; ++ if ((greenShift & 0x7) != 0) ++ return false; ++ if ((blueShift & 0x7) != 0) ++ return false; + + return true; + } diff -Nru tigervnc-1.9.0+dfsg/debian/patches/series tigervnc-1.9.0+dfsg/debian/patches/series --- tigervnc-1.9.0+dfsg/debian/patches/series 2018-12-01 21:51:29.000000000 +0000 +++ tigervnc-1.9.0+dfsg/debian/patches/series 2020-01-23 18:02:51.000000000 +0000 @@ -35,3 +35,8 @@ #dustbin/CVE-2017-7392-Delete-underlying-ssecurity-in-SSecurityVeNCrypt.patch # applied upstream in TigerVNC 1.8 #dustbin/CVE-2017-7394-0001-Fix-checkNoWait-logic-in-SSecurityPlain.patch # applied upstream in TigerVNC 1.8 #dustbin/CVE-2017-7394-0002-Limit-max-username-password-size-in-SSecurityPlain.patch # applied upstream in TigerVNC 1.8 +CVE-2019-15691.patch +CVE-2019-15692.patch +CVE-2019-15693.patch +CVE-2019-15694.patch +CVE-2019-15695.patch