Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian....@packages.debian.org
Usertags: pu

Security fixes for CVE-2019-15691, CVE-2019-15692, CVE-2019-15693,
CVE-2019-15694, and CVE-2019-15695 as detailed in bug #947428.

-- System Information:
Debian Release: 9.11
  APT prefers oldstable
  APT policy: (990, 'oldstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.19.0-6-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru tigervnc-1.7.0+dfsg/debian/changelog 
tigervnc-1.7.0+dfsg/debian/changelog
--- tigervnc-1.7.0+dfsg/debian/changelog        2017-04-09 16:38:13.000000000 
+0200
+++ tigervnc-1.7.0+dfsg/debian/changelog        2020-01-18 19:30:42.000000000 
+0100
@@ -1,3 +1,11 @@
+tigervnc (1.7.0+dfsg-7+deb9u1) stretch; 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 <joachim.f...@gmx.de>  Sat, 18 Jan 2020 19:30:42 +0100
+
 tigervnc (1.7.0+dfsg-7) unstable; urgency=high

   [ Joachim Falk ]
diff -Nru tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15691.patch 
tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15691.patch
--- tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15691.patch     1970-01-01 
01:00:00.000000000 +0100
+++ tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15691.patch     2020-01-18 
19:30:42.000000000 +0100
@@ -0,0 +1,116 @@
+From d61a767d6842b530ffb532ddd5a3d233119aad40 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <oss...@cendio.se>
+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
+@@ -177,7 +177,8 @@ void ZRLE_DECODE (const Rect& r, rdr::In
+     }
+   }
+
+-  zis->removeUnderlying();
++  zis->flushUnderlying();
++  zis->setUnderlying(NULL, 0);
+ }
+
+ #undef ZRLE_DECODE
diff -Nru tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15692.patch 
tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15692.patch
--- tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15692.patch     1970-01-01 
01:00:00.000000000 +0100
+++ tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15692.patch     2020-01-18 
19:30:42.000000000 +0100
@@ -0,0 +1,350 @@
+From 996356b6c65ca165ee1ea46a571c32a1dc3c3821 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <oss...@cendio.se>
+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() {}
+@@ -80,6 +91,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,
+@@ -106,7 +128,7 @@ void ModifiablePixelBuffer::fillRect(con
+   drect = r;
+   if (!drect.enclosed_by(getRect())) {
+     vlog.error("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
+-               drect.width(), drect.height(), drect.tl.x, drect.tl.y, width_, 
height_);
++               drect.width(), drect.height(), drect.tl.x, drect.tl.y, 
width(), height());
+     drect = drect.intersect(getRect());
+   }
+
+@@ -264,7 +286,7 @@ void ModifiablePixelBuffer::copyRect(con
+   drect = rect;
+   if (!drect.enclosed_by(getRect())) {
+     vlog.error("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
+-               drect.width(), drect.height(), drect.tl.x, drect.tl.y, width_, 
height_);
++               drect.width(), drect.height(), drect.tl.x, drect.tl.y, 
width(), height());
+     drect = drect.intersect(getRect());
+   }
+
+@@ -274,7 +296,7 @@ void ModifiablePixelBuffer::copyRect(con
+   srect = drect.translate(move_by_delta.negate());
+   if (!srect.enclosed_by(getRect())) {
+     vlog.error("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d",
+-               srect.width(), srect.height(), srect.tl.x, srect.tl.y, width_, 
height_);
++               srect.width(), srect.height(), srect.tl.x, srect.tl.y, 
width(), height());
+     srect = srect.intersect(getRect());
+     // Need to readjust the destination now that the area has changed
+     drect = srect.translate(move_by_delta);
+@@ -369,19 +391,41 @@ const rdr::U8* FullFramePixelBuffer::get
+   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 Exception("Invalid call to FullFramePixelBuffer::setSize()");
++}
++
+ // -=- Managed pixel buffer class
+ // Automatically allocates enough space for the specified format & area
+
+ ManagedPixelBuffer::ManagedPixelBuffer()
+   : 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), datasize(0)
+ {
+-  checkDataSize();
++  setSize(w, h);
+ };
+
+ ManagedPixelBuffer::~ManagedPixelBuffer() {
+@@ -391,22 +435,18 @@ ManagedPixelBuffer::~ManagedPixelBuffer(
+
+ 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);
+   if (datasize < new_datasize) {
+-    vlog.debug("reallocating managed buffer (%dx%d)", width_, height_);
++    vlog.debug("reallocating managed buffer (%dx%d)", w, h);
+     if (data) {
+       delete [] data;
+-      datasize = 0; data = 0;
++      data = NULL;
++      datasize = 0;
+     }
+     if (new_datasize) {
+       data = new U8[new_datasize];
+@@ -415,4 +455,6 @@ ManagedPixelBuffer::checkDataSize() {
+       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
+@@ -211,8 +211,7 @@ void RenderedCursor::update(PixelBuffer*
+     throw Exception("RenderedCursor: Trying to render cursor on incompatible 
frame buffer");
+
+   format = framebuffer->getPF();
+-  width_ = framebuffer->width();
+-  height_ = framebuffer->height();
++  setSize(framebuffer->width(), framebuffer->height());
+
+   rawOffset = pos.subtract(cursor->hotspot);
+   clippedRect = cursor->getRect(rawOffset).intersect(framebuffer->getRect());
+Index: pkg-tigervnc/common/rfb/PixelBuffer.h
+===================================================================
+--- pkg-tigervnc.orig/common/rfb/PixelBuffer.h
++++ pkg-tigervnc/common/rfb/PixelBuffer.h
+@@ -89,7 +89,10 @@ namespace rfb {
+
+   protected:
+     PixelBuffer();
++    virtual void setSize(int width, int height);
++
+     PixelFormat format;
++  private:
+     int width_, height_;
+   };
+
+@@ -163,7 +166,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);
+
++  protected:
+     rdr::U8* data;
+     int stride;
+   };
+@@ -182,11 +190,10 @@ 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:
+     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
+@@ -891,11 +891,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/unix/xserver/hw/vnc/XserverDesktop.cc
+===================================================================
+--- pkg-tigervnc.orig/unix/xserver/hw/vnc/XserverDesktop.cc
++++ pkg-tigervnc/unix/xserver/hw/vnc/XserverDesktop.cc
+@@ -123,7 +123,7 @@ XserverDesktop::XserverDesktop(int scree
+   : screenIndex(screenIndex_),
+     server(0), httpServer(0),
+     listeners(listeners_), httpListeners(httpListeners_),
+-    deferredUpdateTimerSet(false), directFbptr(true),
++    deferredUpdateTimerSet(false), shadowFramebuffer(NULL),
+     queryConnectId(0)
+ {
+   format = pf;
+@@ -161,13 +161,13 @@ XserverDesktop::~XserverDesktop()
+   }
+   while (!httpListeners.empty()) {
+ #if XORG >= 119
+-    RemoveNotifyFd(listeners.back()->getFd());
++    RemoveNotifyFd(httpListeners.back()->getFd());
+ #endif
+     delete httpListeners.back();
+     httpListeners.pop_back();
+   }
+-  if (!directFbptr)
+-    delete [] data;
++  if (shadowFramebuffer)
++    delete [] shadowFramebuffer;
+   delete httpServer;
+   delete server;
+ }
+@@ -186,22 +186,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_);
+
+   layout = computeScreenLayout();
+
+@@ -1013,7 +1009,7 @@ unsigned int XserverDesktop::setScreenLa
+
+ void XserverDesktop::grabRegion(const rfb::Region& region)
+ {
+-  if (directFbptr)
++  if (shadowFramebuffer == NULL)
+     return;
+
+   std::vector<rfb::Rect> 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
+@@ -123,7 +123,7 @@ private:
+   std::list<network::TcpListener*> listeners;
+   std::list<network::TcpListener*> httpListeners;
+   bool deferredUpdateTimerSet;
+-  bool directFbptr;
++  rdr::U8* shadowFramebuffer;
+   struct timeval dixTimeout;
+
+   uint32_t queryConnectId;
diff -Nru tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15693.patch 
tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15693.patch
--- tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15693.patch     1970-01-01 
01:00:00.000000000 +0100
+++ tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15693.patch     2020-01-18 
19:30:42.000000000 +0100
@@ -0,0 +1,75 @@
+From b4ada8d0c6dac98c8b91fc64d112569a8ae5fb95 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <oss...@cendio.se>
+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.7.0+dfsg/debian/patches/CVE-2019-15694.patch 
tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15694.patch
--- tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15694.patch     1970-01-01 
01:00:00.000000000 +0100
+++ tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15694.patch     2020-01-18 
19:30:42.000000000 +0100
@@ -0,0 +1,1369 @@
+From 0943c006c7d900dfc0281639e992791d6c567438 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <oss...@cendio.se>
+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
+@@ -36,16 +36,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();
+@@ -53,10 +54,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;
+@@ -67,8 +68,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
+@@ -50,7 +50,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)
+ {
+@@ -78,7 +78,7 @@ void FdOutStream::setBlocking(bool block
+   blocking = blocking_;
+ }
+
+-int FdOutStream::length()
++size_t FdOutStream::length()
+ {
+   return offset + ptr - sentUpTo;
+ }
+@@ -96,9 +96,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) && blocking)
+@@ -114,7 +114,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");
+@@ -123,10 +123,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);
+@@ -144,7 +144,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;
+@@ -160,7 +160,7 @@ int FdOutStream::overrun(int itemSize, i
+ // select() and write() 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<b ? a : b;}
+
+-HexInStream::HexInStream(InStream& is, int bufSize_)
++HexInStream::HexInStream(InStream& is, size_t bufSize_)
+ : bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
+ {
+   ptr = end = start = new U8[bufSize];
+@@ -50,8 +50,8 @@ bool HexInStream::readHexAndShift(char c
+   return true;
+ }
+
+-bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
+-  int l=strlen(s);
++bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
++  size_t l=strlen(s);
+   if ((l % 2) == 0) {
+     delete [] *data;
+     *data = 0; *length = 0;
+@@ -59,7 +59,7 @@ bool HexInStream::hexStrToBin(const char
+       return true;
+     *data = new char[l/2];
+     *length = l/2;
+-    for(int i=0;i<l;i+=2) {
++    for(size_t i=0;i<l;i+=2) {
+       int byte = 0;
+       if (!readHexAndShift(s[i], &byte) ||
+         !readHexAndShift(s[i+1], &byte))
+@@ -76,11 +76,11 @@ decodeError:
+ }
+
+
+-int HexInStream::pos() {
++size_t HexInStream::pos() {
+   return offset + ptr - start;
+ }
+
+-int HexInStream::overrun(int itemSize, int nItems, bool wait) {
++size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) {
+   if (itemSize > 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<length; i++) {
++    for (size_t i=0; i<length; i++) {
+       int v = 0;
+       readHexAndShift(iptr[i*2], &v);
+       readHexAndShift(iptr[i*2+1], &v);
+@@ -110,7 +110,7 @@ int HexInStream::overrun(int itemSize, i
+     end += length;
+   }
+
+-  if (itemSize * nItems > 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<b ? a : b;}
++static inline size_t min(size_t a, size_t b) {return a<b ? a : b;}
+
+-HexOutStream::HexOutStream(OutStream& os, int buflen)
++HexOutStream::HexOutStream(OutStream& os, size_t buflen)
+ : out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
+ {
+   if (bufSize % 2)
+@@ -48,9 +48,9 @@ char HexOutStream::intToHex(int i) {
+     throw rdr::Exception("intToHex failed");
+ }
+
+-char* HexOutStream::binToHexStr(const char* data, int length) {
++char* HexOutStream::binToHexStr(const char* data, size_t length) {
+   char* buffer = new char[length*2+1];
+-  for (int i=0; i<length; i++) {
++  for (size_t i=0; i<length; i++) {
+     buffer[i*2] = intToHex((data[i] >> 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<length; i++) {
++    for (size_t i=0; i<length; i++) {
+       optr[i*2] = intToHex((pos[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<length; i++)
++    for (size_t i=0; i<length; i++)
+       *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
+   }
+
+-  if (itemSize * nItems > 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
+@@ -410,7 +410,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];
+@@ -430,7 +430,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());
+@@ -451,7 +451,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
+@@ -245,23 +245,24 @@ 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);
+     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<l ? plainPwd.buf[i] : 0;
+   deskey(d3desObfuscationKey, EN0);
+Index: pkg-tigervnc/common/rfb/Password.h
+===================================================================
+--- pkg-tigervnc.orig/common/rfb/Password.h
++++ pkg-tigervnc/common/rfb/Password.h
+@@ -28,7 +28,7 @@ namespace rfb {
+   public:
+     PlainPasswd();
+     PlainPasswd(char* pwd);
+-    PlainPasswd(int len);
++    PlainPasswd(size_t len);
+     PlainPasswd(const ObfuscatedPasswd& obfPwd);
+     ~PlainPasswd();
+     void replaceBuf(char* b);
+@@ -37,10 +37,10 @@ namespace rfb {
+   class ObfuscatedPasswd : public CharArray {
+   public:
+     ObfuscatedPasswd();
+-    ObfuscatedPasswd(int l);
++    ObfuscatedPasswd(size_t l);
+     ObfuscatedPasswd(const PlainPasswd& plainPwd);
+     ~ObfuscatedPasswd();
+-    int length;
++    size_t length;
+   };
+
+ }
+Index: pkg-tigervnc/common/rfb/util.h
+===================================================================
+--- pkg-tigervnc.orig/common/rfb/util.h
++++ pkg-tigervnc/common/rfb/util.h
+@@ -45,7 +45,7 @@ namespace rfb {
+   public:
+     CharArray() : buf(0) {}
+     CharArray(char* str) : buf(str) {} // note: assumes ownership
+-    CharArray(int len) {
++    CharArray(size_t len) {
+       buf = new char[len];
+     }
+     ~CharArray() {
+Index: pkg-tigervnc/tests/encperf.cxx
+===================================================================
+--- pkg-tigervnc.orig/tests/encperf.cxx
++++ pkg-tigervnc/tests/encperf.cxx
+@@ -71,11 +71,11 @@ class DummyOutStream : public rdr::OutSt
+ public:
+   DummyOutStream();
+
+-  virtual int length();
++  virtual size_t length();
+   virtual void flush();
+
+ private:
+-  virtual int overrun(int itemSize, int nItems);
++  virtual size_t overrun(size_t itemSize, size_t nItems);
+
+   int offset;
+   rdr::U8 buf[131072];
+@@ -141,7 +141,7 @@ DummyOutStream::DummyOutStream()
+   end = buf + sizeof(buf);
+ }
+
+-int DummyOutStream::length()
++size_t DummyOutStream::length()
+ {
+   flush();
+   return offset;
+@@ -153,7 +153,7 @@ void DummyOutStream::flush()
+   ptr = buf;
+ }
+
+-int DummyOutStream::overrun(int itemSize, int nItems)
++size_t DummyOutStream::overrun(size_t itemSize, size_t nItems)
+ {
+   flush();
+   if (itemSize * nItems > 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.7.0+dfsg/debian/patches/CVE-2019-15695.patch 
tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15695.patch
--- tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15695.patch     1970-01-01 
01:00:00.000000000 +0100
+++ tigervnc-1.7.0+dfsg/debian/patches/CVE-2019-15695.patch     2020-01-18 
19:30:42.000000000 +0100
@@ -0,0 +1,32 @@
+From 05e28490873a861379c943bf616614b78b558b89 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <oss...@cendio.se>
+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 exection.
+
+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
+@@ -199,6 +199,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.7.0+dfsg/debian/patches/series 
tigervnc-1.7.0+dfsg/debian/patches/series
--- tigervnc-1.7.0+dfsg/debian/patches/series   2017-04-09 16:38:13.000000000 
+0200
+++ tigervnc-1.7.0+dfsg/debian/patches/series   2020-01-18 19:30:42.000000000 
+0100
@@ -55,3 +55,8 @@
 CVE-2017-7392-Delete-underlying-ssecurity-in-SSecurityVeNCrypt.patch
 CVE-2017-7394-0001-Fix-checkNoWait-logic-in-SSecurityPlain.patch
 CVE-2017-7394-0002-Limit-max-username-password-size-in-SSecurityPlain.patch
+CVE-2019-15691.patch
+CVE-2019-15692.patch
+CVE-2019-15693.patch
+CVE-2019-15694.patch
+CVE-2019-15695.patch

Reply via email to