From 8215c2e14faf332551df61c2ea1c10de84b5de9b Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Thu, 16 Apr 2020 16:10:31 -0400 Subject: [PATCH] import tigervnc-1.9.0-14.el8_1 --- .gitignore | 1 + .tigervnc.metadata | 1 + SOURCES/0001-rpath-hack.patch | 28 + SOURCES/10-libvnc.conf | 19 + SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch | 74 + ...o-not-die-when-port-is-already-taken.patch | 14 + SOURCES/tigervnc-CVE-2019-15691.patch | 116 ++ SOURCES/tigervnc-CVE-2019-15692.patch | 71 + SOURCES/tigervnc-CVE-2019-15693.patch | 75 + SOURCES/tigervnc-CVE-2019-15694.patch | 1419 +++++++++++++++++ SOURCES/tigervnc-CVE-2019-15695.patch | 17 + ...rite-protection-to-offsetpixelbuffer.patch | 51 + ...ve-about-overflows-in-stream-objects.patch | 355 +++++ SOURCES/tigervnc-covscan.patch | 312 ++++ SOURCES/tigervnc-cursor.patch | 12 + ...psulate-pixelbuffer-internal-details.patch | 526 ++++++ SOURCES/tigervnc-getmaster.patch | 88 + ...w-about-not-using-view-only-password.patch | 13 + SOURCES/tigervnc-manpages.patch | 28 + ...rvnc-passwd-crash-with-malloc-checks.patch | 13 + .../tigervnc-pixelformat-sanity-checks.patch | 32 + SOURCES/tigervnc-shebang.patch | 9 + ...ervnc-utilize-system-crypto-policies.patch | 13 + ...t-return-returncode-indicating-error.patch | 13 + ...tigervnc-working-tls-on-fips-systems.patch | 13 + SOURCES/tigervnc-xserver120.patch | 91 ++ SOURCES/tigervnc-xstartup.patch | 40 + SOURCES/vncserver-system.service | 45 + SOURCES/vncserver-user.service | 59 + SOURCES/vncserver.sysconfig | 1 + SOURCES/vncserver_wrapper | 42 + SOURCES/xvnc.service | 38 + SOURCES/xvnc.socket | 9 + SPECS/tigervnc.spec | 1060 ++++++++++++ 34 files changed, 4698 insertions(+) create mode 100644 .gitignore create mode 100644 .tigervnc.metadata create mode 100644 SOURCES/0001-rpath-hack.patch create mode 100644 SOURCES/10-libvnc.conf create mode 100644 SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch create mode 100644 SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch create mode 100644 SOURCES/tigervnc-CVE-2019-15691.patch create mode 100644 SOURCES/tigervnc-CVE-2019-15692.patch create mode 100644 SOURCES/tigervnc-CVE-2019-15693.patch create mode 100644 SOURCES/tigervnc-CVE-2019-15694.patch create mode 100644 SOURCES/tigervnc-CVE-2019-15695.patch create mode 100644 SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch create mode 100644 SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch create mode 100644 SOURCES/tigervnc-covscan.patch create mode 100644 SOURCES/tigervnc-cursor.patch create mode 100644 SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch create mode 100644 SOURCES/tigervnc-getmaster.patch create mode 100644 SOURCES/tigervnc-let-user-know-about-not-using-view-only-password.patch create mode 100644 SOURCES/tigervnc-manpages.patch create mode 100644 SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch create mode 100644 SOURCES/tigervnc-pixelformat-sanity-checks.patch create mode 100644 SOURCES/tigervnc-shebang.patch create mode 100644 SOURCES/tigervnc-utilize-system-crypto-policies.patch create mode 100644 SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch create mode 100644 SOURCES/tigervnc-working-tls-on-fips-systems.patch create mode 100644 SOURCES/tigervnc-xserver120.patch create mode 100644 SOURCES/tigervnc-xstartup.patch create mode 100644 SOURCES/vncserver-system.service create mode 100644 SOURCES/vncserver-user.service create mode 100644 SOURCES/vncserver.sysconfig create mode 100755 SOURCES/vncserver_wrapper create mode 100644 SOURCES/xvnc.service create mode 100644 SOURCES/xvnc.socket create mode 100644 SPECS/tigervnc.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bcdfabc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/tigervnc-1.9.0.tar.gz diff --git a/.tigervnc.metadata b/.tigervnc.metadata new file mode 100644 index 0000000..60dae98 --- /dev/null +++ b/.tigervnc.metadata @@ -0,0 +1 @@ +c56656c596fb863bb2c4b67fb62b4165011d181f SOURCES/tigervnc-1.9.0.tar.gz diff --git a/SOURCES/0001-rpath-hack.patch b/SOURCES/0001-rpath-hack.patch new file mode 100644 index 0000000..689de34 --- /dev/null +++ b/SOURCES/0001-rpath-hack.patch @@ -0,0 +1,28 @@ +From 2489f2f38eb32d9dd03718a36cbdbdf13d2f8b9b Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 12 Nov 2015 11:10:11 -0500 +Subject: [PATCH] rpath hack + +Normally, rpath is undesirable. But for the X server we _know_ we need +Mesa's libGL, which will always be in %{_libdir}, and not any third-party +libGL that may be configured using ld.so.conf. + +--- + configure.ac | 1 + + 1 files changed, 1 insertions(+), 0 deletion(-) + +diff --git a/configure.ac b/configure.ac +index fa15a2d..a5af1e0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1357,6 +1357,7 @@ else + fi + AM_CONDITIONAL(GLX, test "x$GLX" = xyes) + ++GLX_SYS_LIBS="$GLX_SYS_LIBS -Wl,-rpath=\$(libdir)" + AC_SUBST([GLX_DEFINES]) + AC_SUBST([GLX_SYS_LIBS]) + +-- +2.5.0 + diff --git a/SOURCES/10-libvnc.conf b/SOURCES/10-libvnc.conf new file mode 100644 index 0000000..259d718 --- /dev/null +++ b/SOURCES/10-libvnc.conf @@ -0,0 +1,19 @@ +# This file contains configuration of libvnc.so module +# +# To get libvnc.so module working, do this: +# 1. run "vncpasswd" from tigervnc-server package as root user +# 2. uncomment configuration lines below +# +# Please note you can specify any option which Xvnc accepts. +# Refer to `Xvnc -help` output for detailed list of options. + +#Section "Module" +# Load "vnc" +#EndSection + +#Section "Screen" +# Identifier "Screen0" +# DefaultDepth 16 +# Option "SecurityTypes" "VncAuth" +# Option "PasswordFile" "/root/.vnc/passwd" +#EndSection diff --git a/SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch b/SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch new file mode 100644 index 0000000..09217f1 --- /dev/null +++ b/SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch @@ -0,0 +1,74 @@ +diff --git a/unix/x0vncserver/Image.cxx b/unix/x0vncserver/Image.cxx +index f998c6a..fb9dbd4 100644 +--- a/unix/x0vncserver/Image.cxx ++++ b/unix/x0vncserver/Image.cxx +@@ -80,6 +80,14 @@ void Image::Init(int width, int height) + xim = XCreateImage(dpy, vis, DefaultDepth(dpy, DefaultScreen(dpy)), + ZPixmap, 0, 0, width, height, BitmapPad(dpy), 0); + ++ if (xim->bytes_per_line <= 0 || ++ xim->height <= 0 || ++ xim->height >= INT_MAX / xim->bytes_per_line) { ++ vlog.error("Invalid display size"); ++ XDestroyImage(xim); ++ exit(1); ++ } ++ + xim->data = (char *)malloc(xim->bytes_per_line * xim->height); + if (xim->data == NULL) { + vlog.error("malloc() failed"); +@@ -256,6 +264,17 @@ void ShmImage::Init(int width, int height, const XVisualInfo *vinfo) + return; + } + ++ if (xim->bytes_per_line <= 0 || ++ xim->height <= 0 || ++ xim->height >= INT_MAX / xim->bytes_per_line) { ++ vlog.error("Invalid display size"); ++ XDestroyImage(xim); ++ xim = NULL; ++ delete shminfo; ++ shminfo = NULL; ++ return; ++ } ++ + shminfo->shmid = shmget(IPC_PRIVATE, + xim->bytes_per_line * xim->height, + IPC_CREAT|0777); +diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx +index a2b506d..9266d9f 100644 +--- a/vncviewer/PlatformPixelBuffer.cxx ++++ b/vncviewer/PlatformPixelBuffer.cxx +@@ -49,6 +49,15 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : + if (!xim) + throw rdr::Exception("XCreateImage"); + ++ if (xim->bytes_per_line <= 0 || ++ xim->height <= 0 || ++ xim->height >= INT_MAX / xim->bytes_per_line) { ++ if (xim) ++ XDestroyImage(xim); ++ xim = NULL; ++ throw rdr::Exception("Invalid display size"); ++ } ++ + xim->data = (char*)malloc(xim->bytes_per_line * xim->height); + if (!xim->data) + throw rdr::Exception("malloc"); +@@ -152,6 +161,16 @@ bool PlatformPixelBuffer::setupShm() + if (!xim) + goto free_shminfo; + ++ if (xim->bytes_per_line <= 0 || ++ xim->height <= 0 || ++ xim->height >= INT_MAX / xim->bytes_per_line) { ++ XDestroyImage(xim); ++ xim = NULL; ++ delete shminfo; ++ shminfo = NULL; ++ throw rdr::Exception("Invalid display size"); ++ } ++ + shminfo->shmid = shmget(IPC_PRIVATE, + xim->bytes_per_line * xim->height, + IPC_CREAT|0600); diff --git a/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch b/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch new file mode 100644 index 0000000..3623b14 --- /dev/null +++ b/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch @@ -0,0 +1,14 @@ +diff --git a/unix/vncserver b/unix/vncserver +index a6c890f..687ef72 100755 +--- a/unix/vncserver ++++ b/unix/vncserver +@@ -208,7 +208,8 @@ if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) { + $displayNumber = $1; + shift(@ARGV); + if (!&CheckDisplayNumber($displayNumber)) { +- die "A VNC server is already running as :$displayNumber\n"; ++ warn "A VNC server is already running as :$displayNumber\n"; ++ $displayNumber = &GetDisplayNumber(); + } + } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) { + &Usage(); diff --git a/SOURCES/tigervnc-CVE-2019-15691.patch b/SOURCES/tigervnc-CVE-2019-15691.patch new file mode 100644 index 0000000..1b0a6c8 --- /dev/null +++ b/SOURCES/tigervnc-CVE-2019-15691.patch @@ -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(-) + +diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx +index 4053bd1..a361010 100644 +--- a/common/rdr/ZlibInStream.cxx ++++ b/common/rdr/ZlibInStream.cxx +@@ -52,16 +52,16 @@ int ZlibInStream::pos() + return offset + ptr - start; + } + +-void ZlibInStream::removeUnderlying() ++void ZlibInStream::flushUnderlying() + { + ptr = end = start; +- if (!underlying) return; + + while (bytesIn > 0) { + decompress(true); + end = start; // throw away any data + } +- underlying = 0; ++ ++ setUnderlying(NULL, 0); + } + + void ZlibInStream::reset() +@@ -90,7 +90,7 @@ void ZlibInStream::init() + void ZlibInStream::deinit() + { + assert(zs != NULL); +- removeUnderlying(); ++ setUnderlying(NULL, 0); + inflateEnd(zs); + delete zs; + zs = NULL; +@@ -100,8 +100,6 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait) + { + if (itemSize > bufSize) + throw Exception("ZlibInStream overrun: max itemSize exceeded"); +- if (!underlying) +- throw Exception("ZlibInStream overrun: no underlying stream"); + + if (end - ptr != 0) + memmove(start, ptr, end - ptr); +@@ -127,6 +125,9 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait) + + bool ZlibInStream::decompress(bool wait) + { ++ if (!underlying) ++ throw Exception("ZlibInStream overrun: no underlying stream"); ++ + zs->next_out = (U8*)end; + zs->avail_out = start + bufSize - end; + +diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h +index 6bd4da4..86ba1ff 100644 +--- a/common/rdr/ZlibInStream.h ++++ b/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(); + +diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx +index 3a1254a..4273eb7 100644 +--- a/common/rfb/TightDecoder.cxx ++++ b/common/rfb/TightDecoder.cxx +@@ -340,7 +340,8 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer, + + zis[streamId].readBytes(netbuf, dataSize); + +- zis[streamId].removeUnderlying(); ++ zis[streamId].flushUnderlying(); ++ zis[streamId].setUnderlying(NULL, 0); + delete ms; + + bufptr = netbuf; +diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h +index 0bfbbe1..a69ca67 100644 +--- a/common/rfb/zrleDecode.h ++++ b/common/rfb/zrleDecode.h +@@ -178,7 +178,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, + } + } + +- zis->removeUnderlying(); ++ zis->flushUnderlying(); ++ zis->setUnderlying(NULL, 0); + } + + #undef ZRLE_DECODE diff --git a/SOURCES/tigervnc-CVE-2019-15692.patch b/SOURCES/tigervnc-CVE-2019-15692.patch new file mode 100644 index 0000000..4b0e983 --- /dev/null +++ b/SOURCES/tigervnc-CVE-2019-15692.patch @@ -0,0 +1,71 @@ +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 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(+) + +diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx +index ad58324..18f41f8 100644 +--- a/common/rfb/PixelBuffer.cxx ++++ b/common/rfb/PixelBuffer.cxx +@@ -31,6 +31,14 @@ 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 + +@@ -108,6 +116,11 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, + + 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; + } +@@ -337,6 +350,15 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons + 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_; diff --git a/SOURCES/tigervnc-CVE-2019-15693.patch b/SOURCES/tigervnc-CVE-2019-15693.patch new file mode 100644 index 0000000..1e5f152 --- /dev/null +++ b/SOURCES/tigervnc-CVE-2019-15693.patch @@ -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(-) + +diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h +index b6e86ed5e..8f77aebd0 100644 +--- a/common/rfb/tightDecode.h ++++ b/common/rfb/tightDecode.h +@@ -56,15 +56,17 @@ TightDecoder::FilterGradient24(const rdr::U8 *inbuf, + 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 rdr::U8* inbuf, + 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 --git a/SOURCES/tigervnc-CVE-2019-15694.patch b/SOURCES/tigervnc-CVE-2019-15694.patch new file mode 100644 index 0000000..8f3fc27 --- /dev/null +++ b/SOURCES/tigervnc-CVE-2019-15694.patch @@ -0,0 +1,1419 @@ +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 +- + tests/perf/encperf.cxx | 10 +++++----- + win/rfb_win32/Registry.cxx | 6 +++--- + win/rfb_win32/Registry.h | 6 +++--- + 32 files changed, 184 insertions(+), 182 deletions(-) + +diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx +index 011ebf4..789cbec 100644 +--- a/common/rdr/FdInStream.cxx ++++ b/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 timeoutms_, int bufSize_, + } + + 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(FdInStreamBlockCallback* blockCallback_) + 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, int length) + + 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, int length) + } + + +-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, int nItems, bool wait) + 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, int nItems, bool wait) + // 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, int nItems, bool wait) + // 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) +diff --git a/common/rdr/FdInStream.h b/common/rdr/FdInStream.h +index b4c8765..d99ad3c 100644 +--- a/common/rdr/FdInStream.h ++++ b/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; + }; + +diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx +index cf857f8..1757dc3 100644 +--- a/common/rdr/FdOutStream.cxx ++++ b/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 blocking_) { + 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, int nItems) + 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, int nItems) + } + + // 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, int nItems) + // 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; + +diff --git a/common/rdr/FdOutStream.h b/common/rdr/FdOutStream.h +index b7f6cb0..ed84fdb 100644 +--- a/common/rdr/FdOutStream.h ++++ b/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; +diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx +index 3acdfd4..94f5db8 100644 +--- a/common/rdr/FileInStream.cxx ++++ b/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, int nItems, bool wait) + end += b + sizeof(b) - end; + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +diff --git a/common/rdr/FileInStream.h b/common/rdr/FileInStream.h +index ace04f3..a33c765 100644 +--- a/common/rdr/FileInStream.h ++++ b/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]; +diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx +index 80f8a79..8f93988 100644 +--- a/common/rdr/HexInStream.cxx ++++ b/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, int nItems, bool wait) { + 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; +diff --git a/common/rdr/HexInStream.h b/common/rdr/HexInStream.h +index 6bfb843..8e495fb 100644 +--- a/common/rdr/HexInStream.h ++++ b/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; + }; +diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx +index 9b0b6c4..7232514 100644 +--- a/common/rdr/HexOutStream.cxx ++++ b/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; +diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h +index 10247e6..92442a7 100644 +--- a/common/rdr/HexOutStream.h ++++ b/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; + }; + + } +diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h +index 212a2ec..14ecf09 100644 +--- a/common/rdr/InStream.h ++++ b/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: + +diff --git a/common/rdr/MemInStream.h b/common/rdr/MemInStream.h +index 1a6a798..3e9e77b 100644 +--- a/common/rdr/MemInStream.h ++++ b/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; + }; +diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h +index 3b17e55..4a815b3 100644 +--- a/common/rdr/MemOutStream.h ++++ b/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]; +diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h +index a749a20..11aafd2 100644 +--- a/common/rdr/OutStream.h ++++ b/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: + +diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx +index 3fde18d..7681095 100644 +--- a/common/rdr/RandomStream.cxx ++++ b/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, int nItems, bool wait) { + 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, int nItems, bool wait) { + #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, int nItems, bool wait) { + { + #endif + #endif +- for (int i=0; i end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +diff --git a/common/rdr/RandomStream.h b/common/rdr/RandomStream.h +index c33360d..80b389b 100644 +--- a/common/rdr/RandomStream.h ++++ b/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 +diff --git a/common/rdr/SubstitutingInStream.h b/common/rdr/SubstitutingInStream.h +index 325b01c..1466fef 100644 +--- a/common/rdr/SubstitutingInStream.h ++++ b/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"); + +diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx +index 77b1672..d0f9426 100644 +--- a/common/rdr/TLSInStream.cxx ++++ b/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, int nItems, bool wait) + 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; + +diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h +index b16d9f5..5f9dee7 100644 +--- a/common/rdr/TLSInStream.h ++++ b/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; + }; + }; +diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx +index 44d2d9f..30c456f 100644 +--- a/common/rdr/TLSOutStream.cxx ++++ b/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; + +diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h +index 81dd237..71a7f3b 100644 +--- a/common/rdr/TLSOutStream.h ++++ b/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; + }; + }; + +diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx +index a361010..e2f971c 100644 +--- a/common/rdr/ZlibInStream.cxx ++++ b/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, int nItems, bool wait) + 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); +diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h +index 86ba1ff..08784b0 100644 +--- a/common/rdr/ZlibInStream.h ++++ b/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; + }; + +diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx +index 9d9f8ba..4e7ffd6 100644 +--- a/common/rdr/ZlibOutStream.cxx ++++ b/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(int level) + 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, int nItems) + + 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, int nItems) + } + } + +- if (itemSize * nItems > end - ptr) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + + return nItems; +diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h +index 2d82a13..11bb046 100644 +--- a/common/rdr/ZlibOutStream.h ++++ b/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; + }; +diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx +index 619c4d5..f35b0bc 100644 +--- a/common/rfb/Configuration.cxx ++++ b/common/rfb/Configuration.cxx +@@ -421,7 +421,7 @@ StringParameter::operator const char *() const { + // -=- 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 char* v) { + 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() const { + 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_) { +diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h +index 6197317..e23e8a5 100644 +--- a/common/rfb/Configuration.h ++++ b/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 +diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx +index 240c9d4..e4a508c 100644 +--- a/common/rfb/Password.cxx ++++ b/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) ++ if (itemSize * nItems > (size_t)(end - ptr)) + nItems = (end - ptr) / itemSize; + return nItems; + } +diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx +index 963a36a..87086ad 100644 +--- a/win/rfb_win32/Registry.cxx ++++ b/win/rfb_win32/Registry.cxx +@@ -146,7 +146,7 @@ void RegKey::setString(const TCHAR* valname, const TCHAR* value) const { + if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result); + } + +-void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const { ++void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const { + LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length); + if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result); + } +@@ -169,12 +169,12 @@ TCHAR* RegKey::getString(const TCHAR* valname, const TCHAR* def) const { + } + } + +-void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const { ++void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const { + TCharArray hex(getRepresentation(valname)); + if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length)) + throw rdr::Exception("getBinary failed"); + } +-void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const { ++void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const { + try { + getBinary(valname, data, length); + } catch(rdr::Exception&) { +diff --git a/win/rfb_win32/Registry.h b/win/rfb_win32/Registry.h +index 68d535c..2bb1691 100644 +--- a/win/rfb_win32/Registry.h ++++ b/win/rfb_win32/Registry.h +@@ -71,15 +71,15 @@ namespace rfb { + + void setExpandString(const TCHAR* valname, const TCHAR* s) const; + void setString(const TCHAR* valname, const TCHAR* s) const; +- void setBinary(const TCHAR* valname, const void* data, int length) const; ++ void setBinary(const TCHAR* valname, const void* data, size_t length) const; + void setInt(const TCHAR* valname, int i) const; + void setBool(const TCHAR* valname, bool b) const; + + TCHAR* getString(const TCHAR* valname) const; + TCHAR* getString(const TCHAR* valname, const TCHAR* def) const; + +- void getBinary(const TCHAR* valname, void** data, int* length) const; +- void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const; ++ void getBinary(const TCHAR* valname, void** data, size_t* length) const; ++ void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const; + + int getInt(const TCHAR* valname) const; + int getInt(const TCHAR* valname, int def) const; diff --git a/SOURCES/tigervnc-CVE-2019-15695.patch b/SOURCES/tigervnc-CVE-2019-15695.patch new file mode 100644 index 0000000..44c380c --- /dev/null +++ b/SOURCES/tigervnc-CVE-2019-15695.patch @@ -0,0 +1,17 @@ +diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx +index a9d015d..896f4e5 100644 +--- a/common/rfb/PixelFormat.cxx ++++ b/common/rfb/PixelFormat.cxx +@@ -200,6 +200,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 --git a/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch b/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch new file mode 100644 index 0000000..39216f2 --- /dev/null +++ b/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch @@ -0,0 +1,51 @@ +From 9f615301aba1cc54a749950bf9462c5a85217bc4 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 10 Sep 2019 15:25:30 +0200 +Subject: [PATCH] Add write protection to OffsetPixelBuffer + +No one should every try to write to this buffer. Enforce that by +throwing an exception if any one tries to get a writeable pointer +to the data. +--- + common/rfb/EncodeManager.cxx | 6 ++++++ + common/rfb/EncodeManager.h | 3 +++ + 2 files changed, 9 insertions(+) + +diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx +index 1653cea..66ba432 100644 +--- a/common/rfb/EncodeManager.cxx ++++ b/common/rfb/EncodeManager.cxx +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -895,6 +896,11 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf, + setBuffer(width, height, (rdr::U8*)data_, stride_); + } + ++rdr::U8* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& r, int* stride) ++{ ++ throw rfb::Exception("Invalid write attempt to OffsetPixelBuffer"); ++} ++ + // Preprocessor generated, optimised methods + + #define BPP 8 +diff --git a/common/rfb/EncodeManager.h b/common/rfb/EncodeManager.h +index 79db950..7d47420 100644 +--- a/common/rfb/EncodeManager.h ++++ b/common/rfb/EncodeManager.h +@@ -124,6 +124,9 @@ namespace rfb { + + void update(const PixelFormat& pf, int width, int height, + const rdr::U8* data_, int stride); ++ ++ private: ++ virtual rdr::U8* getBufferRW(const Rect& r, int* stride); + }; + + OffsetPixelBuffer offsetPixelBuffer; diff --git a/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch b/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch new file mode 100644 index 0000000..032d4c7 --- /dev/null +++ b/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch @@ -0,0 +1,355 @@ +From 75e6e0653a48baf474fd45d78b1da53e2f324642 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 24 Sep 2019 09:41:07 +0200 +Subject: [PATCH] Be defensive about overflows in stream objects + +We use a lot of lengths given to us over the network, so be more +paranoid about them causing an overflow as otherwise an attacker +might trick us in to overwriting other memory. + +This primarily affects the client which often gets lengths from the +server, but there are also some scenarios where the server might +theoretically be vulnerable. + +Issue found by Pavel Cheremushkin from Kaspersky Lab. +--- + common/rdr/FdInStream.cxx | 8 +++++--- + common/rdr/FdOutStream.cxx | 7 ++++--- + common/rdr/FileInStream.cxx | 8 +++++--- + common/rdr/HexInStream.cxx | 8 +++++--- + common/rdr/HexOutStream.cxx | 6 ++++-- + common/rdr/InStream.h | 24 +++++++++++++----------- + common/rdr/MemOutStream.h | 4 ++++ + common/rdr/OutStream.h | 24 +++++++++++++----------- + common/rdr/RandomStream.cxx | 6 ++++-- + common/rdr/TLSInStream.cxx | 10 ++++++---- + common/rdr/TLSOutStream.cxx | 6 ++++-- + common/rdr/ZlibInStream.cxx | 6 ++++-- + common/rdr/ZlibOutStream.cxx | 6 ++++-- + 13 files changed, 75 insertions(+), 48 deletions(-) + +diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx +index 789cbec..406ece5 100644 +--- a/common/rdr/FdInStream.cxx ++++ b/common/rdr/FdInStream.cxx +@@ -136,7 +136,7 @@ size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) + ptr = start; + + size_t bytes_to_read; +- while (end < start + itemSize) { ++ while ((size_t)(end - start) < itemSize) { + bytes_to_read = start + bufSize - end; + if (!timing) { + // When not timing, we must be careful not to read too much +@@ -152,8 +152,10 @@ size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) + end += n; + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx +index 1757dc3..f5d07e4 100644 +--- a/common/rdr/FdOutStream.cxx ++++ b/common/rdr/FdOutStream.cxx +@@ -149,9 +149,10 @@ size_t FdOutStream::overrun(size_t itemSize, size_t nItems) + } + } + +- // Can we fit all the items asked for? +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx +index 94f5db8..bdb05a3 100644 +--- a/common/rdr/FileInStream.cxx ++++ b/common/rdr/FileInStream.cxx +@@ -68,7 +68,7 @@ size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) + ptr = b; + + +- while (end < b + itemSize) { ++ while ((size_t)(end - b) < itemSize) { + size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file); + if (n == 0) { + if (ferror(file)) +@@ -80,8 +80,10 @@ size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) + end += b + sizeof(b) - end; + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx +index 8f93988..a6bc92c 100644 +--- a/common/rdr/HexInStream.cxx ++++ b/common/rdr/HexInStream.cxx +@@ -91,7 +91,7 @@ size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) { + offset += ptr - start; + ptr = start; + +- while (end < ptr + itemSize) { ++ while ((size_t)(end - ptr) < itemSize) { + size_t n = in_stream.check(2, 1, wait); + if (n == 0) return 0; + const U8* iptr = in_stream.getptr(); +@@ -110,8 +110,10 @@ size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) { + end += length; + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx +index 7232514..eac2eff 100644 +--- a/common/rdr/HexOutStream.cxx ++++ b/common/rdr/HexOutStream.cxx +@@ -102,8 +102,10 @@ HexOutStream::overrun(size_t itemSize, size_t nItems) { + + writeBuffer(); + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h +index 14ecf09..f71a4d9 100644 +--- a/common/rdr/InStream.h ++++ b/common/rdr/InStream.h +@@ -43,12 +43,15 @@ namespace rdr { + + inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true) + { +- if (ptr + itemSize * nItems > end) { +- if (ptr + itemSize > end) +- return overrun(itemSize, nItems, wait); ++ size_t nAvail; ++ ++ if (itemSize > (size_t)(end - ptr)) ++ return overrun(itemSize, nItems, wait); ++ ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + +- nItems = (end - ptr) / itemSize; +- } + return nItems; + } + +@@ -93,13 +96,12 @@ namespace rdr { + // readBytes() reads an exact number of bytes. + + void readBytes(void* data, size_t length) { +- U8* dataPtr = (U8*)data; +- U8* dataEnd = dataPtr + length; +- while (dataPtr < dataEnd) { +- size_t n = check(1, dataEnd - dataPtr); +- memcpy(dataPtr, ptr, n); ++ while (length > 0) { ++ size_t n = check(1, length); ++ memcpy(data, ptr, n); + ptr += n; +- dataPtr += n; ++ data = (U8*)data + n; ++ length -= n; + } + } + +diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h +index 4a815b3..b56bac3 100644 +--- a/common/rdr/MemOutStream.h ++++ b/common/rdr/MemOutStream.h +@@ -23,6 +23,7 @@ + #ifndef __RDR_MEMOUTSTREAM_H__ + #define __RDR_MEMOUTSTREAM_H__ + ++#include + #include + + namespace rdr { +@@ -65,6 +66,9 @@ namespace rdr { + if (len < (size_t)(end - start) * 2) + len = (end - start) * 2; + ++ if (len < (size_t)(end - start)) ++ throw Exception("Overflow in MemOutStream::overrun()"); ++ + U8* newStart = new U8[len]; + memcpy(newStart, start, ptr - start); + ptr = newStart + (ptr - start); +diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h +index 11aafd2..0f60ccc 100644 +--- a/common/rdr/OutStream.h ++++ b/common/rdr/OutStream.h +@@ -46,12 +46,15 @@ namespace rdr { + + inline size_t check(size_t itemSize, size_t nItems=1) + { +- if (ptr + itemSize * nItems > end) { +- if (ptr + itemSize > end) +- return overrun(itemSize, nItems); ++ size_t nAvail; ++ ++ if (itemSize > (size_t)(end - ptr)) ++ return overrun(itemSize, nItems); ++ ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + +- nItems = (end - ptr) / itemSize; +- } + return nItems; + } + +@@ -91,13 +94,12 @@ namespace rdr { + // writeBytes() writes an exact number of bytes. + + void writeBytes(const void* data, size_t length) { +- const U8* dataPtr = (const U8*)data; +- const U8* dataEnd = dataPtr + length; +- while (dataPtr < dataEnd) { +- size_t n = check(1, dataEnd - dataPtr); +- memcpy(ptr, dataPtr, n); ++ while (length > 0) { ++ size_t n = check(1, length); ++ memcpy(ptr, data, n); + ptr += n; +- dataPtr += n; ++ data = (U8*)data + n; ++ length -= n; + } + } + +diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx +index 7681095..6c64ac5 100644 +--- a/common/rdr/RandomStream.cxx ++++ b/common/rdr/RandomStream.cxx +@@ -123,8 +123,10 @@ size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) { + *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx +index d0f9426..3e1172f 100644 +--- a/common/rdr/TLSInStream.cxx ++++ b/common/rdr/TLSInStream.cxx +@@ -43,7 +43,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) + return -1; + } + +- if (in->getend() - in->getptr() < (ptrdiff_t)size) ++ if ((size_t)(in->getend() - in->getptr()) < size) + size = in->getend() - in->getptr(); + + in->readBytes(data, size); +@@ -92,15 +92,17 @@ size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait) + end -= ptr - start; + ptr = start; + +- while (end < start + itemSize) { ++ while ((size_t)(end - start) < itemSize) { + size_t n = readTLS((U8*) end, start + bufSize - end, wait); + if (!wait && n == 0) + return 0; + end += n; + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx +index 30c456f..7d7c3b5 100644 +--- a/common/rdr/TLSOutStream.cxx ++++ b/common/rdr/TLSOutStream.cxx +@@ -100,8 +100,10 @@ size_t TLSOutStream::overrun(size_t itemSize, size_t nItems) + + flush(); + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx +index e2f971c..9fcfaf6 100644 +--- a/common/rdr/ZlibInStream.cxx ++++ b/common/rdr/ZlibInStream.cxx +@@ -113,8 +113,10 @@ size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait) + return 0; + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } +diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx +index 4e7ffd6..5e158bf 100644 +--- a/common/rdr/ZlibOutStream.cxx ++++ b/common/rdr/ZlibOutStream.cxx +@@ -127,8 +127,10 @@ size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) + } + } + +- if (itemSize * nItems > (size_t)(end - ptr)) +- nItems = (end - ptr) / itemSize; ++ size_t nAvail; ++ nAvail = (end - ptr) / itemSize; ++ if (nAvail < nItems) ++ return nAvail; + + return nItems; + } diff --git a/SOURCES/tigervnc-covscan.patch b/SOURCES/tigervnc-covscan.patch new file mode 100644 index 0000000..803f71a --- /dev/null +++ b/SOURCES/tigervnc-covscan.patch @@ -0,0 +1,312 @@ +diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx +index 51d77c76..9e277cbb 100644 +--- a/common/network/TcpSocket.cxx ++++ b/common/network/TcpSocket.cxx +@@ -736,7 +736,7 @@ char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) { + buffer + 1, sizeof (buffer) - 2, NULL, 0, NI_NUMERICHOST); + strcat(buffer, "]"); + addr.buf = rfb::strDup(buffer); +- } else if (p.address.u.sa.sa_family == AF_UNSPEC) ++ } else + addr.buf = rfb::strDup(""); + + char action; +diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx +index e1a31f78..d268202b 100644 +--- a/common/rfb/CSecurityTLS.cxx ++++ b/common/rfb/CSecurityTLS.cxx +@@ -95,9 +95,9 @@ void CSecurityTLS::setDefaults() + delete [] homeDir; + + if (!fileexists(caDefault.buf)) +- X509CA.setDefaultStr(strdup(caDefault.buf)); ++ X509CA.setDefaultStr(caDefault.buf); + if (!fileexists(crlDefault.buf)) +- X509CRL.setDefaultStr(strdup(crlDefault.buf)); ++ X509CRL.setDefaultStr(crlDefault.buf); + } + + void CSecurityTLS::shutdown(bool needbye) +diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx +index 6d48b65c..6f72432a 100644 +--- a/common/rfb/SSecurityPlain.cxx ++++ b/common/rfb/SSecurityPlain.cxx +@@ -41,7 +41,7 @@ StringParameter PasswordValidator::plainUsers + + bool PasswordValidator::validUser(const char* username) + { +- CharArray users(strDup(plainUsers.getValueStr())), user; ++ CharArray users(plainUsers.getValueStr()), user; + + while (users.buf) { + strSplit(users.buf, ',', &user.buf, &users.buf); +diff --git a/unix/tx/TXWindow.cxx b/unix/tx/TXWindow.cxx +index a6819179..6129840e 100644 +--- a/unix/tx/TXWindow.cxx ++++ b/unix/tx/TXWindow.cxx +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + std::list windows; +@@ -132,20 +133,20 @@ TXGlobalEventHandler* TXWindow::setGlobalEventHandler(TXGlobalEventHandler* h) + + void TXWindow::getColours(Display* dpy, XColor* cols, int nCols) + { +- bool* got = new bool[nCols]; ++ std::vector got; ++ + bool failed = false; + int i; + for (i = 0; i < nCols; i++) { + if (XAllocColor(dpy, cmap, &cols[i])) { +- got[i] = true; ++ got.push_back(true); + } else { +- got[i] = false; ++ got.push_back(false); + failed = true; + } + } + + if (!failed) { +- delete [] got; + return; + } + +@@ -168,12 +169,13 @@ void TXWindow::getColours(Display* dpy, XColor* cols, int nCols) + int cmapSize = DisplayCells(dpy,DefaultScreen(dpy)); + + XColor* cm = new XColor[cmapSize]; +- bool* shared = new bool[cmapSize]; +- bool* usedAsNearest = new bool[cmapSize]; ++ std::vector shared; ++ std::vector usedAsNearest; + + for (i = 0; i < cmapSize; i++) { + cm[i].pixel = i; +- shared[i] = usedAsNearest[i] = false; ++ shared.push_back(false); ++ usedAsNearest.push_back(false); + } + + XQueryColors(dpy, cmap, cm, cmapSize); +diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx +index 8bd4e48e..3055223e 100644 +--- a/unix/vncpasswd/vncpasswd.cxx ++++ b/unix/vncpasswd/vncpasswd.cxx +@@ -134,7 +134,7 @@ int main(int argc, char** argv) + } else if (argv[i][0] == '-') { + usage(); + } else if (!fname) { +- fname = argv[i]; ++ fname = strDup(argv[i]); + } else { + usage(); + } +@@ -165,24 +165,37 @@ int main(int argc, char** argv) + FILE* fp = fopen(fname,"w"); + if (!fp) { + fprintf(stderr,"Couldn't open %s for writing\n",fname); ++ delete [] fname; ++ delete obfuscated; ++ delete obfuscatedReadOnly; + exit(1); + } + chmod(fname, S_IRUSR|S_IWUSR); + + if (fwrite(obfuscated->buf, obfuscated->length, 1, fp) != 1) { + fprintf(stderr,"Writing to %s failed\n",fname); ++ delete [] fname; ++ delete obfuscated; ++ delete obfuscatedReadOnly; + exit(1); + } + ++ delete obfuscated; ++ + if (obfuscatedReadOnly) { + if (fwrite(obfuscatedReadOnly->buf, obfuscatedReadOnly->length, 1, fp) != 1) { + fprintf(stderr,"Writing to %s failed\n",fname); ++ delete [] fname; ++ delete obfuscatedReadOnly; + exit(1); + } + } + + fclose(fp); + ++ delete [] fname; ++ delete obfuscatedReadOnly; ++ + return 0; + } + } +diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc +index d6f6b742..7ca71d94 100644 +--- a/unix/xserver/hw/vnc/vncExtInit.cc ++++ b/unix/xserver/hw/vnc/vncExtInit.cc +@@ -184,7 +184,7 @@ void vncExtensionInit(void) + listeners.push_back(new network::TcpListener(vncInetdSock)); + vlog.info("inetd wait"); + } +- } else if (rfbunixpath.getValueStr()[0] != '\0') { ++ } else if (((const char*)rfbunixpath)[0] != '\0') { + char path[PATH_MAX]; + int mode = (int)rfbunixmode; + +@@ -192,7 +192,7 @@ void vncExtensionInit(void) + strncpy(path, rfbunixpath, sizeof(path)); + else + snprintf(path, sizeof(path), "%s.%d", +- rfbunixpath.getValueStr(), scr); ++ (const char*)rfbunixpath, scr); + path[sizeof(path)-1] = '\0'; + + listeners.push_back(new network::UnixListener(path, mode)); +diff --git a/unix/xserver/hw/vnc/vncSelection.c b/unix/xserver/hw/vnc/vncSelection.c +index 51dfd9c6..4f3538d4 100644 +--- a/unix/xserver/hw/vnc/vncSelection.c ++++ b/unix/xserver/hw/vnc/vncSelection.c +@@ -105,7 +105,7 @@ void vncClientCutText(const char* str, int len) + LOG_ERROR("Could not set PRIMARY selection"); + } + +- vncOwnSelection(xaCLIPBOARD); ++ rc = vncOwnSelection(xaCLIPBOARD); + if (rc != Success) + LOG_ERROR("Could not set CLIPBOARD selection"); + } +diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c +index 3b4d2f31..c845ebc4 100644 +--- a/unix/xserver/hw/vnc/xvnc.c ++++ b/unix/xserver/hw/vnc/xvnc.c +@@ -766,10 +766,13 @@ vfbUninstallColormap(ColormapPtr pmap) + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + #else +- dixLookupResourceByType((void * *) &curpmap, pmap->pScreen->defColormap, +- RT_COLORMAP, serverClient, DixUnknownAccess); ++ int rc = dixLookupResourceByType((void * *) &curpmap, pmap->pScreen->defColormap, ++ RT_COLORMAP, serverClient, DixUnknownAccess); ++ if (rc != Success) ++ ErrorF("Failed to uninstall color map\n"); ++ else + #endif +- (*pmap->pScreen->InstallColormap)(curpmap); ++ (*pmap->pScreen->InstallColormap)(curpmap); + } + } + } +diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx +index d070b648..1843485a 100644 +--- a/vncviewer/DesktopWindow.cxx ++++ b/vncviewer/DesktopWindow.cxx +@@ -103,12 +103,12 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, + int geom_x = 0, geom_y = 0; + if (strcmp(geometry, "") != 0) { + int matched; +- matched = sscanf(geometry.getValueStr(), "+%d+%d", &geom_x, &geom_y); ++ matched = sscanf((const char*)geometry, "+%d+%d", &geom_x, &geom_y); + if (matched == 2) { + force_position(1); + } else { + int geom_w, geom_h; +- matched = sscanf(geometry.getValueStr(), "%dx%d+%d+%d", &geom_w, &geom_h, &geom_x, &geom_y); ++ matched = sscanf((const char*)geometry, "%dx%d+%d+%d", &geom_w, &geom_h, &geom_x, &geom_y); + switch (matched) { + case 4: + force_position(1); +diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx +index b018c95b..62b5d9c5 100644 +--- a/vncviewer/OptionsDialog.cxx ++++ b/vncviewer/OptionsDialog.cxx +@@ -282,7 +282,7 @@ void OptionsDialog::loadOptions(void) + /* Screen */ + int width, height; + +- if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) { ++ if (sscanf((const char*)desktopSize, "%dx%d", &width, &height) != 2) { + desktopSizeCheckbox->value(false); + desktopWidthInput->value("1024"); + desktopHeightInput->value("768"); +diff --git a/vncviewer/ServerDialog.cxx b/vncviewer/ServerDialog.cxx +index de67f87b..fec17896 100644 +--- a/vncviewer/ServerDialog.cxx ++++ b/vncviewer/ServerDialog.cxx +@@ -150,7 +150,7 @@ void ServerDialog::handleLoad(Fl_Widget *widget, void *data) + return; + } + +- const char* filename = strdup(file_chooser->value()); ++ const char* filename = file_chooser->value(); + + try { + dialog->serverName->value(loadViewerParameters(filename)); +@@ -165,8 +165,8 @@ void ServerDialog::handleLoad(Fl_Widget *widget, void *data) + void ServerDialog::handleSaveAs(Fl_Widget *widget, void *data) + { + ServerDialog *dialog = (ServerDialog*)data; +- const char* servername = strdup(dialog->serverName->value()); +- char* filename; ++ const char* servername = dialog->serverName->value(); ++ const char* filename; + + Fl_File_Chooser* file_chooser = new Fl_File_Chooser("", _("TigerVNC configuration (*.tigervnc)"), + 2, _("Save the TigerVNC configuration to file")); +@@ -187,7 +187,7 @@ void ServerDialog::handleSaveAs(Fl_Widget *widget, void *data) + return; + } + +- filename = strdup(file_chooser->value()); ++ filename = file_chooser->value(); + + FILE* f = fopen(filename, "r"); + if (f) { +@@ -235,7 +235,7 @@ void ServerDialog::handleCancel(Fl_Widget *widget, void *data) + void ServerDialog::handleConnect(Fl_Widget *widget, void *data) + { + ServerDialog *dialog = (ServerDialog*)data; +- const char* servername = strdup(dialog->serverName->value()); ++ const char* servername = dialog->serverName->value(); + + dialog->hide(); + +diff --git a/vncviewer/parameters.cxx b/vncviewer/parameters.cxx +index 51cce3d7..94cc1b05 100644 +--- a/vncviewer/parameters.cxx ++++ b/vncviewer/parameters.cxx +@@ -499,6 +499,7 @@ void saveViewerParameters(const char *filename, const char *servername) { + } + + snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir); ++ free(homeDir); + } else { + snprintf(filepath, sizeof(filepath), "%s", filename); + } +@@ -555,6 +556,7 @@ char* loadViewerParameters(const char *filename) { + "can't obtain home directory path.")); + + snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir); ++ free(homeDir); + } else { + snprintf(filepath, sizeof(filepath), "%s", filename); + } +diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx +index f076565f..a9d4dfea 100644 +--- a/vncviewer/vncviewer.cxx ++++ b/vncviewer/vncviewer.cxx +@@ -470,9 +470,9 @@ static int mktunnel() + int localPort = findFreeTcpPort(); + int remotePort; + +- gatewayHost = strDup(via.getValueStr()); + if (interpretViaParam(remoteHost, &remotePort, localPort) != 0) + return 1; ++ gatewayHost = (const char*)via; + createTunnel(gatewayHost, remoteHost, remotePort, localPort); + + return 0; diff --git a/SOURCES/tigervnc-cursor.patch b/SOURCES/tigervnc-cursor.patch new file mode 100644 index 0000000..1f95df8 --- /dev/null +++ b/SOURCES/tigervnc-cursor.patch @@ -0,0 +1,12 @@ +diff -up tigervnc-1.3.0/vncviewer/Viewport.cxx.cursor tigervnc-1.3.0/vncviewer/Viewport.cxx +--- tigervnc-1.3.0/vncviewer/Viewport.cxx.cursor 2013-12-17 13:28:23.170400013 +0000 ++++ tigervnc-1.3.0/vncviewer/Viewport.cxx 2013-12-17 13:29:46.095784064 +0000 +@@ -248,7 +248,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot, + } + } + +- if (Fl::belowmouse() == this) ++ if (Fl::belowmouse() == this && cursor) + window()->cursor(cursor, cursorHotspot.x, cursorHotspot.y); + } + diff --git a/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch b/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch new file mode 100644 index 0000000..795a8f1 --- /dev/null +++ b/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch @@ -0,0 +1,526 @@ +From 53f913a76196c7357d4858bfbf2c33caa9181bae Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Tue, 10 Sep 2019 15:18:30 +0200 +Subject: [PATCH] Encapsulate PixelBuffer internal details + +Don't allow subclasses to just override dimensions or buffer details +directly and instead force them to go via methods. This allows us +to do sanity checks on the new values and catch bugs and attacks. +--- + common/rfb/Cursor.cxx | 3 +- + common/rfb/EncodeManager.cxx | 5 +- + common/rfb/PixelBuffer.cxx | 103 ++++++++++++++++---------- + common/rfb/PixelBuffer.h | 17 +++-- + unix/x0vncserver/XPixelBuffer.cxx | 9 +-- + unix/xserver/hw/vnc/XserverDesktop.cc | 24 +++--- + unix/xserver/hw/vnc/XserverDesktop.h | 2 +- + vncviewer/PlatformPixelBuffer.cxx | 9 +-- + win/rfb_win32/DIBSectionBuffer.cxx | 41 ++++------ + 9 files changed, 111 insertions(+), 102 deletions(-) + +diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx +index 99df82d..7f3fc9a 100644 +--- a/common/rfb/Cursor.cxx ++++ b/common/rfb/Cursor.cxx +@@ -271,8 +271,7 @@ void RenderedCursor::update(PixelBuffer* framebuffer, + 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()) +diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx +index 0ce611e..11f31d3 100644 +--- a/common/rfb/EncodeManager.cxx ++++ b/common/rfb/EncodeManager.cxx +@@ -979,11 +979,8 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf, + 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 +diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx +index 007b6c8..ad58324 100644 +--- a/common/rfb/PixelBuffer.cxx ++++ b/common/rfb/PixelBuffer.cxx +@@ -35,8 +35,14 @@ static LogWriter vlog("PixelBuffer"); + // -=- Generic pixel buffer class + + PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h) +- : format(pf), width_(w), height_(h) {} +-PixelBuffer::PixelBuffer() : width_(0), height_(0) {} ++ : format(pf), width_(0), height_(0) ++{ ++ setSize(w, h); ++} ++ ++PixelBuffer::PixelBuffer() : width_(0), height_(0) ++{ ++} + + PixelBuffer::~PixelBuffer() {} + +@@ -53,7 +59,7 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Source 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()); + + data = getBuffer(r, &inStride); + +@@ -89,7 +95,7 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, + if (!r.enclosed_by(getRect())) + throw rfb::Exception("Source 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()); + + if (stride == 0) + stride = r.width(); +@@ -100,6 +106,12 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, + stride, srcStride); + } + ++void PixelBuffer::setSize(int width, int height) ++{ ++ width_ = width; ++ height_ = height; ++} ++ + // -=- Modifiable generic pixel buffer class + + ModifiablePixelBuffer::ModifiablePixelBuffer(const PixelFormat& pf, +@@ -124,7 +136,7 @@ void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix) + + 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 +187,7 @@ void ModifiablePixelBuffer::imageRect(const Rect& r, + 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 +225,13 @@ void ModifiablePixelBuffer::copyRect(const Rect &rect, + 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 +284,7 @@ void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest, + 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 +313,7 @@ rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_) + 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 +328,69 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons + 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_) ++{ ++ 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; +-}; ++ManagedPixelBuffer::~ManagedPixelBuffer() ++{ ++ if (data_) ++ delete [] data_; ++} + ++void ManagedPixelBuffer::setPF(const PixelFormat &pf) ++{ ++ format = pf; ++ setSize(width(), height()); ++} + +-void +-ManagedPixelBuffer::setPF(const PixelFormat &pf) { +- format = pf; checkDataSize(); +-}; +-void +-ManagedPixelBuffer::setSize(int w, int h) { +- width_ = w; height_ = h; stride = w; checkDataSize(); +-}; ++void ManagedPixelBuffer::setSize(int w, int h) ++{ ++ unsigned long new_datasize = w * h * (format.bpp/8); + ++ new_datasize = w * h * (format.bpp/8); + +-inline void +-ManagedPixelBuffer::checkDataSize() { +- unsigned long new_datasize = width_ * height_ * (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) +- throw Exception("rfb::ManagedPixelBuffer unable to allocate buffer"); ++ data_ = new U8[new_datasize]; + datasize = new_datasize; + } + } +-}; ++ ++ setBuffer(w, h, data_, w); ++} +diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h +index d89793f..3e4018f 100644 +--- a/common/rfb/PixelBuffer.h ++++ b/common/rfb/PixelBuffer.h +@@ -90,7 +90,12 @@ namespace rfb { + + protected: + PixelBuffer(); ++ virtual void setSize(int width, int height); ++ ++ protected: + PixelFormat format; ++ ++ private: + int width_, height_; + }; + +@@ -154,7 +159,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; + }; +@@ -172,12 +182,9 @@ namespace rfb { + virtual void setPF(const PixelFormat &pf); + 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); } +- +- protected: ++ private: ++ rdr::U8* data_; // Mirrors FullFramePixelBuffer::data + unsigned long datasize; +- void checkDataSize(); + }; + + }; +diff --git a/unix/x0vncserver/XPixelBuffer.cxx b/unix/x0vncserver/XPixelBuffer.cxx +index 4769b65..f0b0696 100644 +--- a/unix/x0vncserver/XPixelBuffer.cxx ++++ b/unix/x0vncserver/XPixelBuffer.cxx +@@ -50,13 +50,8 @@ XPixelBuffer::XPixelBuffer(Display *dpy, ImageFactory &factory, + 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; +- +- // 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; ++ setBuffer(rect.width(), rect.height(), (rdr::U8 *)m_image->xim->data, ++ 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); +diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc +index 4aac765..78df899 100644 +--- a/unix/xserver/hw/vnc/XserverDesktop.cc ++++ b/unix/xserver/hw/vnc/XserverDesktop.cc +@@ -115,7 +115,7 @@ XserverDesktop::XserverDesktop(int screenIndex_, + : screenIndex(screenIndex_), + server(0), httpServer(0), + listeners(listeners_), httpListeners(httpListeners_), +- directFbptr(true), ++ shadowFramebuffer(NULL), + queryConnectId(0), queryConnectTimer(this) + { + format = pf; +@@ -152,8 +152,8 @@ XserverDesktop::~XserverDesktop() + 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 w, int h, void* fbptr, int stride_) + { + 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::setScreenLayout(int fb_width, int fb_height, + + void XserverDesktop::grabRegion(const rfb::Region& region) + { +- if (directFbptr) ++ if (shadowFramebuffer == NULL) + return; + + std::vector rects; +diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h +index f866a4c..dc4fe60 100644 +--- a/unix/xserver/hw/vnc/XserverDesktop.h ++++ b/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 --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx +index a2b506d..a218901 100644 +--- a/vncviewer/PlatformPixelBuffer.cxx ++++ b/vncviewer/PlatformPixelBuffer.cxx +@@ -36,7 +36,7 @@ static rfb::LogWriter vlog("PlatformPixelBuffer"); + 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) +@@ -56,11 +56,10 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : + 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 + } + +diff --git a/win/rfb_win32/DIBSectionBuffer.cxx b/win/rfb_win32/DIBSectionBuffer.cxx +index e2b0d64..e00cf23 100644 +--- a/win/rfb_win32/DIBSectionBuffer.cxx ++++ b/win/rfb_win32/DIBSectionBuffer.cxx +@@ -52,39 +52,28 @@ void DIBSectionBuffer::setPF(const PixelFormat& pf) { + if (!pf.trueColour) + throw rfb::Exception("palette format not supported"); + format = pf; +- recreateBuffer(); ++ setSize(width(), height()); + } + +-void DIBSectionBuffer::setSize(int w, int h) { +- if (width_ == w && height_ == h) { +- vlog.debug("size unchanged by setSize()"); +- return; +- } +- width_ = w; +- height_ = h; +- recreateBuffer(); +-} +- +- + inline void initMaxAndShift(DWORD mask, int* max, int* shift) { + for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1; + (*max) = (rdr::U16)mask; + } + +-void DIBSectionBuffer::recreateBuffer() { ++void DIBSectionBuffer::setSize(int w, int h) { + HBITMAP new_bitmap = 0; + rdr::U8* new_data = 0; + +- if (width_ && height_ && (format.depth != 0)) { ++ if (w && h && (format.depth != 0)) { + BitmapInfo bi; + memset(&bi, 0, sizeof(bi)); + UINT iUsage = DIB_RGB_COLORS; + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biBitCount = format.bpp; +- bi.bmiHeader.biSizeImage = (format.bpp / 8) * width_ * height_; ++ bi.bmiHeader.biSizeImage = (format.bpp / 8) * w * h; + bi.bmiHeader.biPlanes = 1; +- bi.bmiHeader.biWidth = width_; +- bi.bmiHeader.biHeight = -height_; ++ bi.bmiHeader.biWidth = w; ++ bi.bmiHeader.biHeight = -h; + bi.bmiHeader.biCompression = (format.bpp > 8) ? BI_BITFIELDS : BI_RGB; + bi.mask.red = format.pixelFromRGB((rdr::U16)~0, 0, 0); + bi.mask.green = format.pixelFromRGB(0, (rdr::U16)~0, 0); +@@ -115,12 +104,12 @@ void DIBSectionBuffer::recreateBuffer() { + if (device) { + BitmapDC src_dev(device, bitmap); + BitmapDC dest_dev(device, new_bitmap); +- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY); ++ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY); + } else { + WindowDC wndDC(window); + BitmapDC src_dev(wndDC, bitmap); + BitmapDC dest_dev(wndDC, new_bitmap); +- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY); ++ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY); + } + } + +@@ -128,17 +117,17 @@ void DIBSectionBuffer::recreateBuffer() { + // Delete the old bitmap + DeleteObject(bitmap); + bitmap = 0; +- data = 0; ++ setBuffer(0, 0, NULL, 0); + } + + if (new_bitmap) { + int bpp, depth; + int redMax, greenMax, blueMax; + int redShift, greenShift, blueShift; ++ int new_stride; + + // Set up the new bitmap + bitmap = new_bitmap; +- data = new_data; + + // Determine the *actual* DIBSection format + DIBSECTION ds; +@@ -147,14 +136,16 @@ void DIBSectionBuffer::recreateBuffer() { + + // Correct the "stride" of the DIB + // *** This code DWORD aligns each row - is that right??? +- stride = width_; +- int bytesPerRow = stride * format.bpp/8; ++ new_stride = w; ++ int bytesPerRow = new_stride * format.bpp/8; + if (bytesPerRow % 4) { + bytesPerRow += 4 - (bytesPerRow % 4); +- stride = (bytesPerRow * 8) / format.bpp; +- vlog.info("adjusting DIB stride: %d to %d", width_, stride); ++ new_stride = (bytesPerRow * 8) / format.bpp; ++ vlog.info("adjusting DIB stride: %d to %d", w, new_stride); + } + ++ setBuffer(w, h, new_data, new_stride); ++ + // Calculate the PixelFormat for the DIB + bpp = depth = ds.dsBm.bmBitsPixel; + diff --git a/SOURCES/tigervnc-getmaster.patch b/SOURCES/tigervnc-getmaster.patch new file mode 100644 index 0000000..23c3d58 --- /dev/null +++ b/SOURCES/tigervnc-getmaster.patch @@ -0,0 +1,88 @@ +diff --git a/unix/xserver/hw/vnc/InputXKB.c b/unix/xserver/hw/vnc/InputXKB.c +index a9bd11d..7b54b43 100644 +--- a/unix/xserver/hw/vnc/InputXKB.c ++++ b/unix/xserver/hw/vnc/InputXKB.c +@@ -214,10 +214,7 @@ void vncPrepareInputDevices(void) + + unsigned vncGetKeyboardState(void) + { +- DeviceIntPtr master; +- +- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); +- return XkbStateFieldFromRec(&master->key->xkbInfo->state); ++ return XkbStateFieldFromRec(&vncKeyboardDev->master->key->xkbInfo->state); + } + + unsigned vncGetLevelThreeMask(void) +@@ -238,7 +235,7 @@ unsigned vncGetLevelThreeMask(void) + return 0; + } + +- xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; ++ xkb = vncKeyboardDev->master->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, keycode, state); + if (act == NULL) +@@ -263,7 +260,7 @@ KeyCode vncPressShift(void) + if (state & ShiftMask) + return 0; + +- xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; ++ xkb = vncKeyboardDev->master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; + unsigned char mask; +@@ -303,7 +300,7 @@ size_t vncReleaseShift(KeyCode *keys, size_t maxKeys) + + count = 0; + +- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); ++ master = vncKeyboardDev->master; + xkb = master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; +@@ -359,7 +356,7 @@ KeyCode vncPressLevelThree(void) + return 0; + } + +- xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; ++ xkb = vncKeyboardDev->master->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, keycode, state); + if (act == NULL) +@@ -390,7 +387,7 @@ size_t vncReleaseLevelThree(KeyCode *keys, size_t maxKeys) + + count = 0; + +- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); ++ master = vncKeyboardDev->master; + xkb = master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; +@@ -433,7 +430,7 @@ KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) + if (new_state != NULL) + *new_state = state; + +- xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; ++ xkb = vncKeyboardDev->master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + unsigned int state_out; + KeySym dummy; +@@ -511,7 +508,7 @@ int vncIsAffectedByNumLock(KeyCode keycode) + if (numlock_keycode == 0) + return 0; + +- xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; ++ xkb = vncKeyboardDev->master->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, numlock_keycode, state); + if (act == NULL) +@@ -545,7 +542,7 @@ KeyCode vncAddKeysym(KeySym keysym, unsigned state) + KeySym *syms; + KeySym upper, lower; + +- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); ++ master = vncKeyboardDev->master; + xkb = master->key->xkbInfo->desc; + for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) { + if (XkbKeyNumGroups(xkb, key) == 0) diff --git a/SOURCES/tigervnc-let-user-know-about-not-using-view-only-password.patch b/SOURCES/tigervnc-let-user-know-about-not-using-view-only-password.patch new file mode 100644 index 0000000..e28ffa9 --- /dev/null +++ b/SOURCES/tigervnc-let-user-know-about-not-using-view-only-password.patch @@ -0,0 +1,13 @@ +diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx +index 16c925ee..6398121e 100644 +--- a/unix/vncpasswd/vncpasswd.cxx ++++ b/unix/vncpasswd/vncpasswd.cxx +@@ -150,6 +150,8 @@ int main(int argc, char** argv) + char yesno[3]; + if (fgets(yesno, 3, stdin) != NULL && (yesno[0] == 'y' || yesno[0] == 'Y')) { + obfuscatedReadOnly = readpassword(); ++ } else { ++ fprintf(stderr, "A view-only password is not used\n"); + } + + FILE* fp = fopen(fname,"w"); diff --git a/SOURCES/tigervnc-manpages.patch b/SOURCES/tigervnc-manpages.patch new file mode 100644 index 0000000..8e4b9c9 --- /dev/null +++ b/SOURCES/tigervnc-manpages.patch @@ -0,0 +1,28 @@ +diff --git a/unix/vncserver b/unix/vncserver +index 9e7a6ac..139f960 100755 +--- a/unix/vncserver ++++ b/unix/vncserver +@@ -684,6 +684,7 @@ sub Usage + " [-geometry x]\n". + " [-pixelformat rgbNNN|bgrNNN]\n". + " [-fp ]\n". ++ " [-cc ]\n". + " [-fg]\n". + " [-autokill]\n". + " [-noxstartup]\n". +diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx +index f076565..05669a4 100644 +--- a/vncviewer/vncviewer.cxx ++++ b/vncviewer/vncviewer.cxx +@@ -352,6 +352,11 @@ static void usage(const char *programName) + " %s [parameters] -listen [port] [parameters]\n" + " %s [parameters] [.tigervnc file]\n", + programName, programName, programName); ++ fprintf(stderr,"\n" ++ "Options:\n\n" ++ " -display Xdisplay - Specifies the X display for the viewer window\n" ++ " -geometry geometry - Standard X position and sizing specification.\n"); ++ + fprintf(stderr,"\n" + "Parameters can be turned on with - or off with -=0\n" + "Parameters which take a value can be specified as " diff --git a/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch b/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch new file mode 100644 index 0000000..cf9abae --- /dev/null +++ b/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch @@ -0,0 +1,13 @@ +diff --git a/common/rfb/util.h b/common/rfb/util.h +index b678b89..9e59bd3 100644 +--- a/common/rfb/util.h ++++ b/common/rfb/util.h +@@ -50,7 +50,7 @@ namespace rfb { + CharArray() : buf(0) {} + CharArray(char* str) : buf(str) {} // note: assumes ownership + CharArray(int len) { +- buf = new char[len]; ++ buf = new char[len](); + } + ~CharArray() { + delete [] buf; diff --git a/SOURCES/tigervnc-pixelformat-sanity-checks.patch b/SOURCES/tigervnc-pixelformat-sanity-checks.patch new file mode 100644 index 0000000..9801a5c --- /dev/null +++ b/SOURCES/tigervnc-pixelformat-sanity-checks.patch @@ -0,0 +1,32 @@ +diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx +index 76051dc..a9d015d 100644 +--- a/common/rfb/PixelFormat.cxx ++++ b/common/rfb/PixelFormat.cxx +@@ -75,7 +75,8 @@ PixelFormat::PixelFormat(int b, int d, bool e, bool t, + redMax(rm), greenMax(gm), blueMax(bm), + redShift(rs), greenShift(gs), blueShift(bs) + { +- assert(isSane()); ++ if (!isSane()) ++ throw Exception("invalid pixel format"); + + updateState(); + } +@@ -672,8 +673,16 @@ bool PixelFormat::isSane(void) + return false; + + totalBits = bits(redMax) + bits(greenMax) + bits(blueMax); +- if (totalBits > bpp) ++ if (totalBits > depth) ++ return false; ++ ++ if ((bits(redMax) + redShift) > bpp) ++ return false; ++ if ((bits(greenMax) + greenShift) > bpp) + return false; ++ if ((bits(blueMax) + blueShift) > bpp) ++ return false; ++ + + if (((redMax << redShift) & (greenMax << greenShift)) != 0) + return false; diff --git a/SOURCES/tigervnc-shebang.patch b/SOURCES/tigervnc-shebang.patch new file mode 100644 index 0000000..f76af87 --- /dev/null +++ b/SOURCES/tigervnc-shebang.patch @@ -0,0 +1,9 @@ +diff -up tigervnc-1.3.0/unix/vncserver.shebang tigervnc-1.3.0/unix/vncserver +--- tigervnc-1.3.0/unix/vncserver.shebang 2013-07-24 12:22:34.962158378 +0100 ++++ tigervnc-1.3.0/unix/vncserver 2013-07-24 12:22:41.593188190 +0100 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + # + # Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. + # Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. diff --git a/SOURCES/tigervnc-utilize-system-crypto-policies.patch b/SOURCES/tigervnc-utilize-system-crypto-policies.patch new file mode 100644 index 0000000..dbf0dab --- /dev/null +++ b/SOURCES/tigervnc-utilize-system-crypto-policies.patch @@ -0,0 +1,13 @@ +diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx +index e623ab5..4987b29 100644 +--- a/common/rfb/Security.cxx ++++ b/common/rfb/Security.cxx +@@ -52,7 +52,7 @@ static LogWriter vlog("Security"); + #ifdef HAVE_GNUTLS + StringParameter Security::GnuTLSPriority("GnuTLSPriority", + "GnuTLS priority string that controls the TLS session’s handshake algorithms", +- "NORMAL"); ++ "@SYSTEM"); + #endif + + Security::Security() diff --git a/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch b/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch new file mode 100644 index 0000000..1361d8b --- /dev/null +++ b/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch @@ -0,0 +1,13 @@ +diff --git a/unix/vncserver b/unix/vncserver +index bb4f2feb..68be032d 100755 +--- a/unix/vncserver ++++ b/unix/vncserver +@@ -709,7 +709,7 @@ sub List + } + } + } +- exit 1; ++ exit; + } + + diff --git a/SOURCES/tigervnc-working-tls-on-fips-systems.patch b/SOURCES/tigervnc-working-tls-on-fips-systems.patch new file mode 100644 index 0000000..841ac2f --- /dev/null +++ b/SOURCES/tigervnc-working-tls-on-fips-systems.patch @@ -0,0 +1,13 @@ +diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx +index b946022..2daefa2 100644 +--- a/common/rfb/SSecurityTLS.cxx ++++ b/common/rfb/SSecurityTLS.cxx +@@ -186,7 +186,7 @@ void SSecurityTLS::setParams(gnutls_session_t session) + if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_dh_params_init failed"); + +- if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS) ++ if (gnutls_dh_params_generate2(dh_params, gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM)) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_dh_params_generate2 failed"); + + if (anon) { diff --git a/SOURCES/tigervnc-xserver120.patch b/SOURCES/tigervnc-xserver120.patch new file mode 100644 index 0000000..e7eae3c --- /dev/null +++ b/SOURCES/tigervnc-xserver120.patch @@ -0,0 +1,91 @@ +diff -up xserver/configure.ac.xserver116-rebased xserver/configure.ac +--- xserver/configure.ac.xserver116-rebased 2016-09-29 13:14:45.595441590 +0200 ++++ xserver/configure.ac 2016-09-29 13:14:45.631442006 +0200 +@@ -74,6 +74,7 @@ dnl forcing an entire recompile.x + AC_CONFIG_HEADERS(include/version-config.h) + + AM_PROG_AS ++AC_PROG_CXX + AC_PROG_LN_S + LT_PREREQ([2.2]) + LT_INIT([disable-static win32-dll]) +@@ -1863,6 +1864,10 @@ if test "x$XVFB" = xyes; then + AC_SUBST([XVFB_SYS_LIBS]) + fi + ++dnl Xvnc DDX ++AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"]) ++AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"]) ++AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"]) + + dnl Xnest DDX + +@@ -1898,6 +1903,8 @@ if test "x$XORG" = xauto; then + fi + AC_MSG_RESULT([$XORG]) + ++AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version]) ++ + if test "x$XORG" = xyes; then + XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common' + XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os' +@@ -2116,7 +2123,6 @@ if test "x$XORG" = xyes; then + AC_DEFINE(XORG_SERVER, 1, [Building Xorg server]) + AC_DEFINE(XORGSERVER, 1, [Building Xorg server]) + AC_DEFINE(XFree86Server, 1, [Building XFree86 server]) +- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version]) + AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs]) + AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions]) + AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server]) +@@ -2691,6 +2697,7 @@ hw/dmx/Makefile + hw/dmx/man/Makefile + hw/vfb/Makefile + hw/vfb/man/Makefile ++hw/vnc/Makefile + hw/xnest/Makefile + hw/xnest/man/Makefile + hw/xwin/Makefile +diff -up xserver/hw/Makefile.am.xserver116-rebased xserver/hw/Makefile.am +--- xserver/hw/Makefile.am.xserver116-rebased 2016-09-29 13:14:45.601441659 +0200 ++++ xserver/hw/Makefile.am 2016-09-29 13:14:45.631442006 +0200 +@@ -38,7 +38,8 @@ SUBDIRS = \ + $(DMX_SUBDIRS) \ + $(KDRIVE_SUBDIRS) \ + $(XQUARTZ_SUBDIRS) \ +- $(XWAYLAND_SUBDIRS) ++ $(XWAYLAND_SUBDIRS) \ ++ vnc + + DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland + +diff --git xserver/mi/miinitext.c xserver/mi/miinitext.c +index 5596e21..003fc3c 100644 +--- xserver/mi/miinitext.c ++++ xserver/mi/miinitext.c +@@ -107,8 +107,15 @@ SOFTWARE. + #include "os.h" + #include "globals.h" + ++#ifdef TIGERVNC ++extern void vncExtensionInit(INITARGS); ++#endif ++ + /* List of built-in (statically linked) extensions */ + static const ExtensionModule staticExtensions[] = { ++#ifdef TIGERVNC ++ {vncExtensionInit, "VNC-EXTENSION", NULL}, ++#endif + {GEExtensionInit, "Generic Event Extension", &noGEExtension}, + {ShapeExtensionInit, "SHAPE", NULL}, + #ifdef MITSHM +--- xserver/include/os.h~ 2016-10-03 09:07:29.000000000 +0200 ++++ xserver/include/os.h 2016-10-03 14:13:00.013654506 +0200 +@@ -621,7 +621,7 @@ + extern _X_EXPORT void + LogClose(enum ExitCode error); + extern _X_EXPORT Bool +-LogSetParameter(LogParameter param, int value); ++LogSetParameter(enum _LogParameter param, int value); + extern _X_EXPORT void + LogVWrite(int verb, const char *f, va_list args) + _X_ATTRIBUTE_PRINTF(2, 0); diff --git a/SOURCES/tigervnc-xstartup.patch b/SOURCES/tigervnc-xstartup.patch new file mode 100644 index 0000000..7098941 --- /dev/null +++ b/SOURCES/tigervnc-xstartup.patch @@ -0,0 +1,40 @@ +diff --git a/unix/vncserver b/unix/vncserver +index bb4f2feb..b038dd3b 100755 +--- a/unix/vncserver ++++ b/unix/vncserver +@@ -58,27 +58,14 @@ $defaultXStartup + = ("#!/bin/sh\n\n". + "unset SESSION_MANAGER\n". + "unset DBUS_SESSION_BUS_ADDRESS\n". +- "OS=`uname -s`\n". +- "if [ \$OS = 'Linux' ]; then\n". +- " case \"\$WINDOWMANAGER\" in\n". +- " \*gnome\*)\n". +- " if [ -e /etc/SuSE-release ]; then\n". +- " PATH=\$PATH:/opt/gnome/bin\n". +- " export PATH\n". +- " fi\n". +- " ;;\n". +- " esac\n". +- "fi\n". +- "if [ -x /etc/X11/xinit/xinitrc ]; then\n". +- " exec /etc/X11/xinit/xinitrc\n". +- "fi\n". +- "if [ -f /etc/X11/xinit/xinitrc ]; then\n". +- " exec sh /etc/X11/xinit/xinitrc\n". +- "fi\n". +- "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n". +- "xsetroot -solid grey\n". +- "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n". +- "twm &\n"); ++ "/etc/X11/xinit/xinitrc\n". ++ "# Assume either Gnome will be started by default when installed\n". ++ "# We want to kill the session automatically in this case when user logs out. In case you modify\n". ++ "# /etc/X11/xinit/Xclients or ~/.Xclients yourself to achieve a different result, then you should\n". ++ "# be responsible to modify below code to avoid that your session will be automatically killed\n". ++ "if [ -e /usr/bin/gnome-session ]; then\n". ++ " vncserver -kill \$DISPLAY\n". ++ "fi\n"); + + $defaultConfig + = ("## Supported server options to pass to vncserver upon invocation can be listed\n". diff --git a/SOURCES/vncserver-system.service b/SOURCES/vncserver-system.service new file mode 100644 index 0000000..7b9cb2f --- /dev/null +++ b/SOURCES/vncserver-system.service @@ -0,0 +1,45 @@ +# The vncserver service unit file +# +# Quick HowTo: +# 1. Copy this file to /etc/systemd/system/vncserver@.service +# 2. Replace with the actual user name and edit vncserver +# parameters in the wrapper script located in /usr/bin/vncserver_wrapper +# 3. Run `systemctl daemon-reload` +# 4. Run `systemctl enable vncserver@:.service` +# +# DO NOT RUN THIS SERVICE if your local area network is +# untrusted! For a secure way of using VNC, you should +# limit connections to the local host and then tunnel from +# the machine you want to view VNC on (host A) to the machine +# whose VNC output you want to view (host B) +# +# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB +# +# this will open a connection on port 590N of your hostA to hostB's port 590M +# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). +# See the ssh man page for details on port forwarding) +# +# You can then point a VNC client on hostA at vncdisplay N of localhost and with +# the help of ssh, you end up seeing what hostB makes available on port 590M +# +# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. +# +# Use "-localhost" to prevent remote VNC clients connecting except when +# doing so through a secure tunnel. See the "-via" option in the +# `man vncviewer' manual page. + + +[Unit] +Description=Remote desktop service (VNC) +After=syslog.target network.target + +[Service] +Type=simple + +# Clean any existing files in /tmp/.X11-unix environment +ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' +ExecStart=/usr/bin/vncserver_wrapper %i +ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/vncserver-user.service b/SOURCES/vncserver-user.service new file mode 100644 index 0000000..aed01e0 --- /dev/null +++ b/SOURCES/vncserver-user.service @@ -0,0 +1,59 @@ +# The vncserver service unit file +# +# Quick HowTo: As the User wanting to have this functionality +# +# 1. Copy this file to ~/.config/systemd/user/ (Optional, in case default settings are not suitable) +# +# $ mkdir -p ~/.config/systemd/user +# $ cp /usr/lib/systemd/user/vncserver@.service ~/.config/systemd/user/ +# +# 2. Reload user's systemd +# +# $ systemctl --user daemon-reload +# +# 3. Start the service immediately and enable it at boot +# +# $ systemctl --user enable vncserver@:.service --now +# +# 4. Enable lingering +# +# $ loginctl enable-linger +# +# DO NOT RUN THIS SERVICE if your local area network is +# untrusted! For a secure way of using VNC, you should +# limit connections to the local host and then tunnel from +# the machine you want to view VNC on (host A) to the machine +# whose VNC output you want to view (host B) +# +# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB +# +# this will open a connection on port 590N of your hostA to hostB's port 590M +# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). +# See the ssh man page for details on port forwarding) +# +# You can then point a VNC client on hostA at vncdisplay N of localhost and with +# the help of ssh, you end up seeing what hostB makes available on port 590M +# +# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. +# +# Use "-localhost" to prevent remote VNC clients connecting except when +# doing so through a secure tunnel. See the "-via" option in the +# `man vncviewer' manual page. + + +[Unit] +Description=Remote desktop service (VNC) +After=syslog.target network.target + +[Service] +Type=forking + +ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' +ExecStart=/usr/bin/vncserver %i +ExecStop=/usr/bin/vncserver -kill %i + +Restart=on-success +RestartSec=15 + +[Install] +WantedBy=default.target diff --git a/SOURCES/vncserver.sysconfig b/SOURCES/vncserver.sysconfig new file mode 100644 index 0000000..4d0489b --- /dev/null +++ b/SOURCES/vncserver.sysconfig @@ -0,0 +1 @@ +# THIS FILE HAS BEEN REPLACED BY /lib/systemd/system/vncserver@.service diff --git a/SOURCES/vncserver_wrapper b/SOURCES/vncserver_wrapper new file mode 100755 index 0000000..0c8f994 --- /dev/null +++ b/SOURCES/vncserver_wrapper @@ -0,0 +1,42 @@ +#!/bin/sh + +USER="$1" +INSTANCE="$2" + +die() { + echo "FATAL: ${@:-}" >&2 + exit 2 +} + +cleanup() { + [ -n "$VNCPID" ] || return + if kill -0 $VNCPID 2>/dev/null; then + kill $VNCPID + fi +} + +trap cleanup TERM INT HUP + +[ -n "$USER" -a -n "$INSTANCE" ] || die "Invalid usage!" + +/usr/sbin/runuser -l "$USER" -c "/usr/bin/vncserver ${INSTANCE}" +[ $? -eq 0 ] || die "'runuser -l $USER' failed!" + +# Wait up to 5 seconds for vncserver to be up +for tries in $(seq 1 50); do + [ -e "~$USER/.vnc/$(hostname)${INSTANCE}.pid" ] && break + sleep 0.1 +done + +eval HOME=~$USER + +VNCPID=$(cat "$HOME/.vnc/$(hostname)${INSTANCE}.pid" 2>/dev/null || true) +[ -n "$VNCPID" ] || die "'vncserver ${INSTANCE}' failed to start after 5 seconds!" + +echo "'vncserver ${INSTANCE}' has PID $VNCPID, waiting until it exits ..." + +while kill -0 $VNCPID 2>/dev/null; do + sleep 5 +done + +echo "PID $VNCPID exited, exiting ..." diff --git a/SOURCES/xvnc.service b/SOURCES/xvnc.service new file mode 100644 index 0000000..3471e1f --- /dev/null +++ b/SOURCES/xvnc.service @@ -0,0 +1,38 @@ +# The vncserver service unit file +# +# Quick HowTo: +# 1. Copy this file to /etc/systemd/system/xvnc@.service +# 2. Copy xvnc.socket to /etc/systemd/system/xvnc.socket +# 3. Run `systemctl daemon-reload` +# 4. Run `systemctl enable xvnc.socket` +# +# DO NOT RUN THIS SERVICE if your local area network is +# untrusted! For a secure way of using VNC, you should +# limit connections to the local host and then tunnel from +# the machine you want to view VNC on (host A) to the machine +# whose VNC output you want to view (host B) +# +# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB +# +# this will open a connection on port 590N of your hostA to hostB's port 590M +# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). +# See the ssh man page for details on port forwarding) +# +# You can then point a VNC client on hostA at vncdisplay N of localhost and with +# the help of ssh, you end up seeing what hostB makes available on port 590M +# +# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. +# +# Use "-localhost" to prevent remote VNC clients connecting except when +# doing so through a secure tunnel. See the "-via" option in the +# `man vncviewer' manual page. + + +[Unit] +Description=XVNC Per-Connection Daemon + +[Service] +ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None +User=nobody +StandardInput=socket +StandardError=syslog diff --git a/SOURCES/xvnc.socket b/SOURCES/xvnc.socket new file mode 100644 index 0000000..9b3f92d --- /dev/null +++ b/SOURCES/xvnc.socket @@ -0,0 +1,9 @@ +[Unit] +Description=XVNC Server + +[Socket] +ListenStream=5900 +Accept=yes + +[Install] +WantedBy=sockets.target diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec new file mode 100644 index 0000000..2d291c1 --- /dev/null +++ b/SPECS/tigervnc.spec @@ -0,0 +1,1060 @@ +Name: tigervnc +Version: 1.9.0 +Release: 14%{?dist} +Summary: A TigerVNC remote display system + +%global _hardened_build 1 + +License: GPLv2+ +URL: http://www.tigervnc.com + +Source0: %{name}-%{version}.tar.gz +Source1: vncserver-system.service +Source2: vncserver-user.service +Source3: vncserver.sysconfig +Source4: 10-libvnc.conf +Source5: xvnc.service +Source6: xvnc.socket +Source7: vncserver_wrapper + +Patch1: tigervnc-manpages.patch +Patch2: tigervnc-getmaster.patch +Patch3: tigervnc-shebang.patch +Patch4: tigervnc-xstartup.patch +Patch5: tigervnc-cursor.patch +Patch6: tigervnc-1.3.1-CVE-2014-8240.patch +Patch7: tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch +Patch8: tigervnc-let-user-know-about-not-using-view-only-password.patch +Patch9: tigervnc-working-tls-on-fips-systems.patch +Patch11: tigervnc-utilize-system-crypto-policies.patch +Patch12: tigervnc-passwd-crash-with-malloc-checks.patch +Patch13: tigervnc-vncserver-do-not-return-returncode-indicating-error.patch + +Patch50: tigervnc-covscan.patch + +# Security fixes +Patch200: tigervnc-CVE-2019-15691.patch +Patch201: tigervnc-encapsulate-pixelbuffer-internal-details.patch +Patch202: tigervnc-CVE-2019-15692.patch +Patch203: tigervnc-add-write-protection-to-offsetpixelbuffer.patch +Patch204: tigervnc-CVE-2019-15693.patch +Patch205: tigervnc-pixelformat-sanity-checks.patch +Patch206: tigervnc-CVE-2019-15694.patch +Patch207: tigervnc-be-defensive-about-overflows-in-stream-objects.patch +Patch208: tigervnc-CVE-2019-15695.patch + +# This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg +Patch100: tigervnc-xserver120.patch +# 1326867 - [RHEL7.3] GLX applications in an Xvnc session fails to start +Patch101: 0001-rpath-hack.patch + +BuildRequires: gcc-c++ +BuildRequires: libX11-devel, automake, autoconf, libtool, gettext, gettext-autopoint +BuildRequires: libXext-devel, xorg-x11-server-source, libXi-devel +BuildRequires: xorg-x11-xtrans-devel, xorg-x11-util-macros, libXtst-devel +BuildRequires: libxkbfile-devel, openssl-devel, libpciaccess-devel +BuildRequires: mesa-libGL-devel, libXinerama-devel +BuildRequires: freetype-devel, libXdmcp-devel, libxshmfence-devel +BuildRequires: desktop-file-utils, java-devel, jpackage-utils +BuildRequires: libjpeg-turbo-devel, gnutls-devel, pam-devel +BuildRequires: libdrm-devel, libXt-devel, pixman-devel +BuildRequires: systemd, cmake +%if 0%{?fedora} > 24 || 0%{?rhel} >= 7 +BuildRequires: libXfont2-devel +%else +BuildRequires: libXfont-devel +%endif + +# TigerVNC 1.4.x requires fltk 1.3.3 for keyboard handling support +# See https://github.com/TigerVNC/tigervnc/issues/8, also bug #1208814 +BuildRequires: fltk-devel >= 1.3.3 +%ifnarch s390 s390x +BuildRequires: xorg-x11-server-devel +%endif + +Requires(post): coreutils +Requires(postun):coreutils + +Requires: hicolor-icon-theme +Requires: tigervnc-license +Requires: tigervnc-icons + +%description +Virtual Network Computing (VNC) is a remote display system which +allows you to view a computing 'desktop' environment not only on the +machine where it is running, but from anywhere on the Internet and +from a wide variety of machine architectures. This package contains a +client which will allow you to connect to other desktops running a VNC +server. + +%package server +Summary: A TigerVNC server +Requires: perl-interpreter +Requires: tigervnc-server-minimal +Requires: xorg-x11-xauth +Requires: xorg-x11-xinit +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(post): systemd + +%description server +The VNC system allows you to access the same desktop from a wide +variety of platforms. This package includes set of utilities +which make usage of TigerVNC server more user friendly. It also +contains x0vncserver program which can export your active +X session. + +%package server-minimal +Summary: A minimal installation of TigerVNC server +Requires(post): chkconfig +Requires(preun):chkconfig + +Requires: mesa-dri-drivers, xkeyboard-config, xorg-x11-xkb-utils +Requires: tigervnc-license + +%description server-minimal +The VNC system allows you to access the same desktop from a wide +variety of platforms. This package contains minimal installation +of TigerVNC server, allowing others to access the desktop on your +machine. + +%ifnarch s390 s390x +%package server-module +Summary: TigerVNC module to Xorg +Requires: xorg-x11-server-Xorg %(xserver-sdk-abi-requires ansic) %(xserver-sdk-abi-requires videodrv) +Requires: tigervnc-license + +%description server-module +This package contains libvnc.so module to X server, allowing others +to access the desktop on your machine. +%endif + +%package server-applet +Summary: Java TigerVNC viewer applet for TigerVNC server +Requires: tigervnc-server, java, jpackage-utils +BuildArch: noarch + +%description server-applet +The Java TigerVNC viewer applet for web browsers. Install this package to allow +clients to use web browser when connect to the TigerVNC server. + +%package license +Summary: License of TigerVNC suite +BuildArch: noarch + +%description license +This package contains license of the TigerVNC suite + +%package icons +Summary: Icons for TigerVNC viewer +BuildArch: noarch + +%description icons +This package contains icons for TigerVNC viewer + +%prep +%setup -q + +cp -r /usr/share/xorg-x11-server-source/* unix/xserver +pushd unix/xserver +for all in `find . -type f -perm -001`; do + chmod -x "$all" +done +%patch100 -p1 -b .xserver120-rebased +%patch101 -p1 -b .rpath +popd + +# Synchronise manpages and --help output (bug #980870). +%patch1 -p1 -b .manpages + +# libvnc.so: don't use unexported GetMaster function (bug #744881 again). +%patch2 -p1 -b .getmaster + +# Don't use shebang in vncserver script. +%patch3 -p1 -b .shebang + +# Clearer xstartup file (bug #923655). +# Bug 1665876 - Tigervnc not starting on RHEL 7.6 server without -noxstartup option +%patch4 -p1 -b .xstartup + +# Fixed viewer crash when cursor has not been set (bug #1051333). +%patch5 -p1 -b .cursor + +# CVE-2014-8240 tigervnc: integer overflow flaw, leading to a heap-based +# buffer overflow in screen size handling +%patch6 -p1 -b .tigervnc-1.3.1-CVE-2014-8240 + +# Bug 1322155 - Xorg socket conflict for VNC port 5901 +%patch7 -p1 -b .do-not-die-when-port-is-already-taken + +# Bug 1447555 - view-only accepts enter, unclear whether default password is generated or not +%patch8 -p1 -b .let-user-know-about-not-using-view-only-password + +# Bug 1492107 - VNC cannot be used when FIPS is enabled because DH_BITS is too low +%patch9 -p1 -b .working-tls-on-fips-systems + +# Utilize system-wide crypto policies +%patch11 -p1 -b .utilize-system-crypto-policies.patch + +%patch12 -p1 -b .passwd-crash-with-malloc-checks + +%patch13 -p1 -b .vncserver-do-not-return-returncode-indicating-error + +%patch50 -p1 -b .tigervnc-covscan + +# Security fixes +%patch200 -p1 -b .CVE-2019-15691 +%patch201 -p1 -b .encapsulate-pixelbuffer-internal-details +%patch202 -p1 -b .CVE-2019-15692 +%patch203 -p1 -b .add-write-protection-to-offsetpixelbuffer +%patch204 -p1 -b .CVE-2019-15693 +%patch205 -p1 -b .pixelformat-sanity-checks +%patch206 -p1 -b .CVE-2019-15694 +%patch207 -p1 -b .be-defensive-about-overflows-in-stream-objects +%patch208 -p1 -b .CVE-2019-15695 + +%build +%ifarch sparcv9 sparc64 s390 s390x +export CFLAGS="$RPM_OPT_FLAGS -fPIC" +%else +export CFLAGS="$RPM_OPT_FLAGS -fpic" +%endif +export CXXFLAGS="$CFLAGS" + +%{cmake} . +make %{?_smp_mflags} + +pushd unix/xserver +autoreconf -fiv +%configure \ + --disable-xorg --disable-xnest --disable-xvfb --disable-dmx \ + --disable-xwin --disable-xephyr --disable-kdrive --disable-xwayland \ + --with-pic --disable-static \ + --with-default-font-path="catalogue:%{_sysconfdir}/X11/fontpath.d,built-ins" \ + --with-fontdir=%{_datadir}/X11/fonts \ + --with-xkb-output=%{_localstatedir}/lib/xkb \ + --enable-install-libxf86config \ + --enable-glx --disable-dri --enable-dri2 --disable-dri3 \ + --disable-unit-tests \ + --disable-config-hal \ + --disable-config-udev \ + --with-dri-driver-path=%{_libdir}/dri \ + --without-dtrace \ + --disable-devel-docs \ + --disable-selective-werror + +make %{?_smp_mflags} +popd + +# Build icons +pushd media +make +popd + +# Build Java applet +pushd java +%{cmake} . +JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8" make +popd + +%install +%make_install +rm -f %{buildroot}%{_docdir}/%{name}-%{version}/{README.rst,LICENCE.TXT} + +pushd unix/xserver/hw/vnc +make install DESTDIR=%{buildroot} +popd + +# Install systemd unit file +mkdir -p %{buildroot}%{_unitdir} +mkdir -p %{buildroot}%{_userunitdir} +install -m644 %{SOURCE1} %{buildroot}%{_unitdir}/vncserver@.service +install -m644 %{SOURCE2} %{buildroot}%{_userunitdir}/vncserver@.service +install -m644 %{SOURCE5} %{buildroot}%{_unitdir}/xvnc@.service +install -m644 %{SOURCE6} %{buildroot}%{_unitdir}/xvnc.socket +rm -rf %{buildroot}%{_initrddir} + +# Install vncserver wrapper script +install -m744 %{SOURCE7} %{buildroot}%{_bindir}/vncserver_wrapper + +mkdir -p %{buildroot}%{_sysconfdir}/sysconfig +install -m644 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/vncservers + +# Install desktop stuff +mkdir -p %{buildroot}%{_datadir}/icons/hicolor/{16x16,24x24,48x48}/apps + +pushd media/icons +for s in 16 24 48; do +install -m644 tigervnc_$s.png %{buildroot}%{_datadir}/icons/hicolor/${s}x$s/apps/tigervnc.png +done +popd + + +# Install Java applet +pushd java +mkdir -p %{buildroot}%{_datadir}/vnc/classes +install -m755 VncViewer.jar %{buildroot}%{_datadir}/vnc/classes +install -m644 com/tigervnc/vncviewer/index.vnc %{buildroot}%{_datadir}/vnc/classes +popd + +%find_lang %{name} %{name}.lang + +# remove unwanted files +rm -f %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.la + +%ifarch s390 s390x +rm -f %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.so +%else +mkdir -p %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/ +install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf +%endif + +%post server +%systemd_post vncserver.service +%systemd_post xvnc.service +%systemd_post xvnc.socket + +%preun server +%systemd_preun vncserver.service +%systemd_preun xvnc.service +%systemd_preun xvnc.socket + +%postun server +%systemd_postun vncserver.service +%systemd_postun xvnc.service +%systemd_postun xvnc.socket + +%files -f %{name}.lang +%doc README.rst +%{_bindir}/vncviewer +%{_datadir}/applications/* +%{_mandir}/man1/vncviewer.1* + +%files server +%config(noreplace) %{_sysconfdir}/sysconfig/vncservers +%{_userunitdir}/vncserver@.service +%{_unitdir}/vncserver@.service +%{_unitdir}/xvnc@.service +%{_unitdir}/xvnc.socket +%{_bindir}/x0vncserver +%{_bindir}/vncserver +%{_bindir}/vncserver_wrapper +%{_mandir}/man1/vncserver.1* +%{_mandir}/man1/x0vncserver.1* + +%files server-minimal +%{_bindir}/vncconfig +%{_bindir}/vncpasswd +%{_bindir}/Xvnc +%{_mandir}/man1/Xvnc.1* +%{_mandir}/man1/vncpasswd.1* +%{_mandir}/man1/vncconfig.1* + +%ifnarch s390 s390x +%files server-module +%{_libdir}/xorg/modules/extensions/libvnc.so +%config %{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf +%endif + +%files server-applet +%doc java/com/tigervnc/vncviewer/README +%{_datadir}/vnc/classes/* + +%files license +%license LICENCE.TXT + +%files icons +%{_datadir}/icons/hicolor/*/apps/* + +%changelog +* Thu Apr 09 2020 Jan Grulich - 1.9.0-14 +- Bump build version + Resolves: bz#1819877 + Resolves: bz#1819879 + Resolves: bz#1819882 + Resolves: bz#1819886 + Resolves: bz#1819884 + +* Wed Apr 08 2020 Jan Grulich - 1.9.0-13 +- Fix stack buffer overflow in CMsgReader::readSetCursor + Resolves: bz#1819877 + +- Fix heap buffer overflow in DecodeManager::decodeRect + Resolves: bz#1819879 + +- Fix heap buffer overflow in TightDecoder::FilterGradient + Resolves: bz#1819882 + +- Fix heap-based buffer overflow triggered from CopyRectDecoder + Resolves: bz#1819886 + +- Fix stack use-after-return due to incorrect usage of stack memory in ZRLEDecoder + Resolves: bz#1819884 + +* Tue Jan 28 2020 Jan Grulich - 1.9.0-12 +- Fix installation of 10-libvnc.conf file + Resolves: bz#1795168 + +* Mon Jan 27 2020 Jan Grulich - 1.9.0-11 +- Use wrapper script to workaround systemd issues + Resolves: bz#1795168 + +* Fri Jul 12 2019 Jan Grulich - 1.9.0-10 +- Do not return returncode indicating error when running "vncserver -list" + Resolves: bz#1727860 + +* Fri Feb 08 2019 Jan Grulich - 1.9.0-9 +- Make tigervnc systemd service a user service + Resolves: bz#1639846 + +* Mon Jan 21 2019 Jan Grulich - 1.9.0-8 +- Kill the session automatically only when Gnome is installed + Resolves: bz#1665876 + +* Tue Nov 20 2018 Jan Grulich - 1.9.0-7 +- Improve coverity scan fixes + Resolves: bz#1602714 + + Inform whether view-only password is used or not + Resolves: bz#1639169 + + Backport fixes from RHEL 7 + Resolves: bz#1651254 + +* Tue Oct 09 2018 Jan Grulich - 1.9.0-6 +- Do not crash passwd when using malloc perturb checks + Resolves: bz#1637086 + +* Mon Oct 08 2018 Jan Grulich - 1.9.0-5 +- Improve coverity scan fixes + Resolves: bz#1602714 + +* Wed Oct 03 2018 Jan Grulich - 1.9.0-4 +- Improve coverity scan fixes + Resolves: bz#1602714 + +* Wed Oct 03 2018 Jan Grulich - 1.9.0-3 +- Fix some coverity scan issues + Resolves: bz#1602714 + +* Wed Aug 01 2018 Jan Grulich - 1.9.0-2 +- Remove dependency on initscripts + +* Tue Jul 17 2018 Jan Grulich - 1.9.0-1 +- Update to 1.9.0 + sync with Fedora + +* Tue Jun 12 2018 Adam Jackson - 1.8.0-10 +- Fix GLX initialization with Xorg 1.20 + +* Tue May 29 2018 Jan Grulich - 1.8.0-9 +- Build against Xorg 1.20 + +* Mon May 14 2018 Jan Grulich - 1.8.0-8 +- Drop BR: ImageMagick + +* Fri Feb 09 2018 Fedora Release Engineering - 1.8.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Jan 18 2018 Igor Gnatenko - 1.8.0-6 +- Remove obsolete scriptlets + +* Fri Dec 15 2017 Jan Grulich - 1.8.0-5 +- Properly initialize tigervnc when started as systemd service + +* Thu Aug 03 2017 Fedora Release Engineering - 1.8.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 1.8.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Thu Jul 13 2017 Petr Pisar - 1.8.0-2 +- perl dependency renamed to perl-interpreter + + +* Wed May 17 2017 Jan Grulich - 1.8.0-1 +- Update to 1.8.0 + +* Thu Apr 20 2017 Jan Grulich - 1.7.90-1 +- Update to 1.7.90 (beta) + +* Thu Apr 06 2017 Jan Grulich - 1.7.1-4 +- Added systemd unit file for xvnc + Resolves: bz#891802 + +* Tue Apr 04 2017 Jan Grulich - 1.7.1-3 +- Bug 1438704 - CVE-2017-7392 CVE-2017-7393 CVE-2017-7394 + CVE-2017-7395 CVE-2017-7396 tigervnc: various flaws + + other upstream related fixes + +* Sat Feb 11 2017 Fedora Release Engineering - 1.7.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 19 2017 Jan Grulich - 1.7.1-1 +- Update to 1.7.1 + +* Mon Jan 9 2017 Hans de Goede - 1.7.0-6 +- Fix -inetd no longer working (rhbz#1408724) + +* Wed Nov 30 2016 Jan Grulich - 1.7.0-5 +- Fix broken vncserver.service file + +* Wed Nov 23 2016 Jan Grulich - 1.7.0-4 +- Improve instructions in vncserver.service + Resolves: bz#1397207 + +* Tue Oct 4 2016 Hans de Goede - 1.7.0-3 +- Update tigervnc-1.7.0-xserver119-support.patch to also request write + notfication when necessary + +* Mon Oct 3 2016 Hans de Goede - 1.7.0-2 +- Add patches for use with xserver-1.19 +- Rebuild against xserver-1.19 +- Cleanup specfile a bit + +* Mon Sep 12 2016 Jan Grulich - 1.7.0-1 +- Update to 1.7.0 + +* Mon Jul 18 2016 Jan Grulich - 1.6.90-1 +- Update to 1.6.90 (1.7.0 beta) + +* Wed Jun 01 2016 Jan Grulich - 1.6.0-6 +- Try to pickup upstream fix for compatibility with gtk vnc clients + +* Wed Jun 01 2016 Jan Grulich - 1.6.0-5 +- Re-enable patch4 again, will need to find a way to make this work on both sides + +* Mon May 23 2016 Jan Grulich - 1.6.0-4 +- Utilize system-wide crypto policies + Resolves: bz#1179345 +- Try to disable patch4 as it was previously written to support an + older version of a different client and breaks some other usage + Resolves: bz#1280440 + +* Fri Feb 05 2016 Fedora Release Engineering - 1.6.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 13 2016 Jan Grulich - 1.6.0-2 +- Update systemd service file + Resolves: bz#1211789 + +* Mon Jan 04 2016 Jan Grulich - 1.6.0-1 +- Update to 1.6.0 + +* Tue Dec 01 2015 Jan Grulich - 1.5.90-1 +- Update to 1.5.90 (1.6.0 beta) + +* Thu Nov 19 2015 Jan Grulich - 1.5.0-4 +- rebuild against final xorg server 1.18 release (bug #1279146) + +* Tue Sep 22 2015 Kalev Lember - 1.5.0-3 +- xorg server 1.18 ABI rebuild + +* Fri Aug 21 2015 Jan Grulich - 1.5.0-2 +- Do not fail with -inetd option + +* Wed Aug 19 2015 Jan Grulich - 1.5.0-1 +- 1.5.0 + +* Tue Aug 04 2015 Kevin Fenzi - 1.4.3-12 +- Rebuild to fix broken deps and build against xorg 1.18 prerelease + +* Thu Jun 25 2015 Tim Waugh - 1.4.3-11 +- Rebuilt (bug #1235603). + +* Fri Jun 19 2015 Fedora Release Engineering - 1.4.3-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon May 04 2015 Kalev Lember - 1.4.3-8 +- Rebuilt for nettle soname bump + +* Wed Apr 22 2015 Tim Waugh - 1.4.3-7 +- Removed incorrect parameters from vncviewer manpage (bug #1213199). + +* Tue Apr 21 2015 Tim Waugh - 1.4.3-6 +- Use full git hash for GitHub tarball release. + +* Fri Apr 10 2015 Tim Waugh - 1.4.3-5 +- Explicit version build dependency for fltk (bug #1208814). + +* Thu Apr 9 2015 Tim Waugh - 1.4.3-4 +- Drop upstream xorg-x11-server patch as it is now built (bug #1210407). + +* Thu Apr 9 2015 Tim Waugh - 1.4.3-3 +- Apply upstream patch to fix byte order (bug #1206060). + +* Fri Mar 6 2015 Tim Waugh - 1.4.3-2 +- Don't disable Xinerama extension (upstream #147). + +* Mon Mar 2 2015 Tim Waugh - 1.4.3-1 +- 1.4.3. + +* Tue Feb 24 2015 Tim Waugh - 1.4.2-3 +- Use calloc instead of xmalloc. +- Removed unnecessary configure flags. + +* Wed Feb 18 2015 Rex Dieter 1.4.2-2 +- rebuild (fltk) + +* Fri Feb 13 2015 Tim Waugh - 1.4.2-1 +- Rebased xserver116.patch against xorg-x11-server-1.17.1. +- Allow build against xorg-x11-server-1.17. +- 1.4.2. + +* Tue Sep 9 2014 Tim Waugh - 1.3.1-11 +- Added missing part of xserver114.patch (bug #1137023). + +* Wed Sep 3 2014 Tim Waugh - 1.3.1-10 +- Fix build against xorg-x11-server-1.16.0 (bug #1136532). + +* Mon Aug 18 2014 Fedora Release Engineering - 1.3.1-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 15 2014 Tim Waugh - 1.3.1-8 +- Input reset fixes from upstream (bug #1116956). +- No longer need ppc64le patch as it's now in xorg-x11-server. +- Rebased xserver114.patch again. + +* Fri Jun 20 2014 Hans de Goede - 1.3.1-7 +- xserver 1.15.99.903 ABI rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 1.3.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 22 2014 Tim Waugh 1.3.1-5 +- Keep pointer in sync when using module (upstream bug #152). + +* Mon Apr 28 2014 Adam Jackson 1.3.1-4 +- Add version interlocks for -server-module + +* Mon Apr 28 2014 Hans de Goede - 1.3.1-3 +- xserver 1.15.99-20140428 git snapshot ABI rebuild + +* Mon Apr 7 2014 Tim Waugh 1.3.1-2 +- Allow build with dri3 and present extensions (bug #1063392). + +* Thu Mar 27 2014 Tim Waugh 1.3.1-1 +- 1.3.1 (bug #1078806). +- Add ppc64le support (bug #1078495). + +* Wed Mar 19 2014 Tim Waugh 1.3.0-15 +- Disable dri3 to enable building (bug #1063392). +- Fixed heap-based buffer overflow (CVE-2014-0011, bug #1050928). + +* Fri Feb 21 2014 Tim Waugh 1.3.0-14 +- Enabled hardened build (bug #955206). + +* Mon Feb 10 2014 Tim Waugh 1.3.0-13 +- Clearer xstartup file (bug #923655). + +* Tue Jan 14 2014 Tim Waugh 1.3.0-12 +- Fixed instructions in systemd unit file. + +* Fri Jan 10 2014 Tim Waugh 1.3.0-11 +- Fixed viewer crash when cursor has not been set (bug #1038701). + +* Thu Dec 12 2013 Tim Waugh 1.3.0-10 +- Avoid invalid read when ZRLE connection closed (upstream bug #133). + +* Tue Dec 3 2013 Tim Waugh 1.3.0-9 +- Fixed build failure with -Werror=format-security (bug #1037358). + +* Thu Nov 07 2013 Adam Jackson 1.3.0-8 +- Rebuild against xserver 1.15RC1 + +* Tue Sep 24 2013 Tim Waugh 1.3.0-7 +- Removed incorrect patch (for unexpected key_is_down). Fixes stuck + keys bug (bug #989502). + +* Thu Sep 19 2013 Tim Waugh 1.3.0-6 +- Fixed typo in 10-libvnc.conf (bug #1009111). + +* Wed Sep 18 2013 Tim Waugh 1.3.0-5 +- Better fix for PIDFile problem (bug #983232). + +* Mon Aug 5 2013 Tim Waugh 1.3.0-4 +- Fixed doc-related build failure (bug #992790). + +* Wed Jul 24 2013 Tim Waugh 1.3.0-3 +- Avoid PIDFile problems in systemd unit file (bug #983232). +- libvnc.so: don't use unexported key_is_down function. +- Don't use shebang in vncserver script. + +* Fri Jul 12 2013 Tim Waugh 1.3.0-2 +- Renumbered patches. +- libvnc.so: don't use unexported GetMaster function (bug #744881 again). + +* Mon Jul 8 2013 Tim Waugh 1.3.0-1 +- 1.3.0. + +* Wed Jul 3 2013 Tim Waugh 1.2.80-0.18.20130314svn5065 +- Removed systemd_requires macro in order to fix the build. + +* Wed Jul 3 2013 Tim Waugh 1.2.80-0.17.20130314svn5065 +- Synchronise manpages and --help output (bug #980870). + +* Mon Jun 17 2013 Adam Jackson 1.2.80-0.16.20130314svn5065 +- tigervnc-setcursor-crash.patch: Attempt to paper over a crash in Xvnc when + setting the cursor. + +* Sat Jun 08 2013 Dennis Gilmore 1.2.80-0.15.20130314svn5065 +- bump to rebuild and pick up bugfix causing X to crash on ppc and arm + +* Thu May 23 2013 Tim Waugh 1.2.80-0.14.20130314svn5065 +- Use systemd rpm macros (bug #850340). Moved systemd requirements + from main package to server sub-package. +- Applied Debian patch to fix busy loop when run from inetd in nowait + mode (bug #920373). +- Added dependency on xorg-x11-xinit to server sub-package so that + default window manager can be found (bug #896284, bug #923655). +- Fixed bogus changelog date. + +* Thu Mar 14 2013 Adam Jackson 1.2.80-0.13.20130314svn5065 +- Less RHEL customization + +* Thu Mar 14 2013 Adam Tkac - 1.2.80-0.12.20130314svn5065 +- include /etc/X11/xorg.conf.d/10-libvnc.conf sample configuration (#712482) +- vncserver now honors specified -geometry parameter (#755947) + +* Tue Mar 12 2013 Adam Tkac - 1.2.80-0.11.20130307svn5060 +- update to r5060 +- split icons to separate package to avoid multilib issues + +* Tue Feb 19 2013 Adam Tkac - 1.2.80-0.10.20130219svn5047 +- update to r5047 (X.Org 1.14 support) + +* Fri Feb 15 2013 Fedora Release Engineering - 1.2.80-0.9.20121126svn5015 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Jan 21 2013 Adam Tkac - 1.2.80-0.8.20121126svn5015 +- rebuild due to "jpeg8-ABI" feature drop + +* Wed Jan 16 2013 Adam Tkac 1.2.80-0.7.20121126svn5015 +- rebuild + +* Tue Dec 04 2012 Adam Tkac 1.2.80-0.6.20121126svn5015 +- rebuild against new fltk + +* Mon Nov 26 2012 Adam Tkac 1.2.80-0.5.20121126svn5015 +- update to r5015 +- build with -fpic instead of -fPIC on all archs except s390/sparc + +* Wed Nov 7 2012 Peter Robinson 1.2.80-0.4.20120905svn4996 +- Build with -fPIC to fix FTBFS on ARM + +* Wed Oct 31 2012 Adam Jackson 1.2.80-0.3.20120905svn4996 +- tigervnc12-xorg113-glx.patch: Fix to only init glx on the first server + generation + +* Fri Sep 28 2012 Adam Jackson 1.2.80-0.2.20120905svn4996 +- tigervnc12-xorg113-glx.patch: Re-enable GLX against xserver 1.13 + +* Fri Aug 17 2012 Adam Tkac 1.2.80-0.1.20120905svn4996 +- update to 1.2.80 +- remove deprecated patches + - tigervnc-102434.patch + - tigervnc-viewer-reparent.patch + - tigervnc11-java7.patch +- patches merged + - tigervnc11-xorg111.patch + - tigervnc11-xorg112.patch + +* Fri Aug 10 2012 Dave Airlie 1.1.0-10 +- fix build against newer X server + +* Mon Jul 23 2012 Adam Jackson 1.1.0-9 +- Build with the Composite extension for feature parity with other X servers + +* Sat Jul 21 2012 Fedora Release Engineering - 1.1.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jul 19 2012 Dave Airlie 1.1.0-7 +- fix building against X.org 1.13 + +* Wed Apr 04 2012 Adam Jackson 1.1.0-6 +- RHEL exclusion for -server-module on ppc* too + +* Mon Mar 26 2012 Adam Tkac - 1.1.0-5 +- clean Xvnc's /tmp environment in service file before startup +- fix building against the latest JAVA 7 and X.Org 1.12 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.1.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Nov 22 2011 Adam Tkac - 1.1.0-3 +- don't build X.Org devel docs (#755782) +- applet: BR generic java-devel instead of java-gcj-devel (#755783) +- use runuser to start Xvnc in systemd service file (#754259) +- don't attepmt to restart Xvnc session during update/erase (#753216) + +* Fri Nov 11 2011 Adam Tkac - 1.1.0-2 +- libvnc.so: don't use unexported GetMaster function (#744881) +- remove nasm buildreq + +* Mon Sep 12 2011 Adam Tkac - 1.1.0-1 +- update to 1.1.0 +- update the xorg11 patch +- patches merged + - tigervnc11-glx.patch + - tigervnc11-CVE-2011-1775.patch + - 0001-Use-memmove-instead-of-memcpy-in-fbblt.c-when-memory.patch + +* Thu Jul 28 2011 Adam Tkac - 1.0.90-6 +- add systemd service file and remove legacy SysV initscript (#717227) + +* Thu May 12 2011 Adam Tkac - 1.0.90-5 +- make Xvnc buildable against X.Org 1.11 + +* Tue May 10 2011 Adam Tkac - 1.0.90-4 +- viewer can send password without proper validation of X.509 certs + (CVE-2011-1775) + +* Wed Apr 13 2011 Adam Tkac - 1.0.90-3 +- fix wrong usage of memcpy which caused screen artifacts (#652590) +- don't point to inaccessible link in sysconfig/vncservers (#644975) + +* Fri Apr 08 2011 Adam Tkac - 1.0.90-2 +- improve compatibility with vinagre client (#692048) + +* Tue Mar 22 2011 Adam Tkac - 1.0.90-1 +- update to 1.0.90 + +* Wed Feb 09 2011 Fedora Release Engineering - 1.0.90-0.32.20110117svn4237 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 17 2011 Adam Tkac 1.0.90-0.31.20110117svn4237 +- fix libvnc.so module loading + +* Mon Jan 17 2011 Adam Tkac 1.0.90-0.30.20110117svn4237 +- update to r4237 +- patches merged + - tigervnc11-optionsdialog.patch + - tigervnc11-rh607866.patch + +* Fri Jan 14 2011 Adam Tkac 1.0.90-0.29.20101208svn4225 +- improve patch for keyboard issues + +* Fri Jan 14 2011 Adam Tkac 1.0.90-0.28.20101208svn4225 +- attempt to fix various keyboard-related issues (key repeating etc) + +* Fri Jan 07 2011 Adam Tkac 1.0.90-0.27.20101208svn4225 +- render "Ok" and "Cancel" buttons in the options dialog correctly + +* Wed Dec 15 2010 Jan Görig 1.0.90-0.26.20101208svn4225 +- added vncserver lock file (#662784) + +* Fri Dec 10 2010 Adam Tkac 1.0.90-0.25.20101208svn4225 +- update to r4225 +- patches merged + - tigervnc11-rh611677.patch + - tigervnc11-rh633931.patch + - tigervnc11-xorg1.10.patch +- enable VeNCrypt and PAM support + +* Mon Dec 06 2010 Adam Tkac 1.0.90-0.24.20100813svn4123 +- rebuild against xserver 1.10.X +- 0001-Return-Success-from-generate_modkeymap-when-max_keys.patch merged + +* Wed Sep 29 2010 jkeating - 1.0.90-0.23.20100813svn4123 +- Rebuilt for gcc bug 634757 + +* Tue Sep 21 2010 Adam Tkac 1.0.90-0.22.20100420svn4030 +- drop xorg-x11-fonts-misc dependency (#636170) + +* Tue Sep 21 2010 Adam Tkac 1.0.90-0.21.20100420svn4030 +- improve patch for #633645 (fix tcsh incompatibilities) + +* Thu Sep 16 2010 Adam Tkac 1.0.90-0.20.20100813svn4123 +- press fake modifiers correctly (#633931) +- supress unneeded debug information emitted from initscript (#633645) + +* Wed Aug 25 2010 Adam Tkac 1.0.90-0.19.20100813svn4123 +- separate Xvnc, vncpasswd and vncconfig to -server-minimal subpkg (#626946) +- move license to separate subpkg and Requires it from main subpkgs +- Xvnc: handle situations when no modifiers exist well (#611677) + +* Fri Aug 13 2010 Adam Tkac 1.0.90-0.18.20100813svn4123 +- update to r4123 (#617973) +- add perl requires to -server subpkg (#619791) + +* Thu Jul 22 2010 Adam Tkac 1.0.90-0.17.20100721svn4113 +- update to r4113 +- patches merged + - tigervnc11-rh586406.patch + - tigervnc11-libvnc.patch + - tigervnc11-rh597172.patch + - tigervnc11-rh600070.patch + - tigervnc11-options.patch +- don't own %%{_datadir}/icons directory (#614301) +- minor improvements in the .desktop file (#616340) +- bundled libjpeg configure requires nasm; is executed even if system-wide + libjpeg is used + +* Fri Jul 02 2010 Adam Tkac 1.0.90-0.16.20100420svn4030 +- build against system-wide libjpeg-turbo (#494458) +- build no longer requires nasm + +* Mon Jun 28 2010 Adam Tkac 1.0.90-0.15.20100420svn4030 +- vncserver: accept <+optname> option when specified as the first one + +* Thu Jun 24 2010 Adam Tkac 1.0.90-0.14.20100420svn4030 +- fix memory leak in Xvnc input code (#597172) +- don't crash when receive negative encoding (#600070) +- explicitly disable udev configuration support +- add gettext-autopoint to BR + +* Mon Jun 14 2010 Adam Tkac 1.0.90-0.13.20100420svn4030 +- update URL about SSH tunneling in the sysconfig file (#601996) + +* Fri Jun 11 2010 Adam Tkac 1.0.90-0.12.20100420svn4030 +- use newer gettext +- autopoint now uses git instead of cvs, adjust BuildRequires appropriately + +* Thu May 13 2010 Adam Tkac 1.0.90-0.11.20100420svn4030 +- link libvnc.so "now" to catch "undefined symbol" errors during Xorg startup +- use always XkbConvertCase instead of XConvertCase (#580159, #586406) +- don't link libvnc.so against libXi.la, libdix.la and libxkb.la; use symbols + from Xorg instead + +* Thu May 13 2010 Adam Tkac 1.0.90-0.10.20100420svn4030 +- update to r4030 snapshot +- patches merged to upstream + - tigervnc11-rh522369.patch + - tigervnc11-rh551262.patch + - tigervnc11-r4002.patch + - tigervnc11-r4014.patch + +* Thu Apr 08 2010 Adam Tkac 1.0.90-0.9.20100219svn3993 +- add server-applet subpackage which contains Java vncviewer applet +- fix Java applet; it didn't work when run from web browser +- add xorg-x11-xkb-utils to server Requires + +* Fri Mar 12 2010 Adam Tkac 1.0.90-0.8.20100219svn3993 +- add French translation to vncviewer.desktop (thanks to Alain Portal) + +* Thu Mar 04 2010 Adam Tkac 1.0.90-0.7.20100219svn3993 +- don't crash during pixel format change (#522369, #551262) + +* Mon Mar 01 2010 Adam Tkac 1.0.90-0.6.20100219svn3993 +- add mesa-dri-drivers and xkeyboard-config to -server Requires +- update to r3993 1.0.90 snapshot + - tigervnc11-noexecstack.patch merged + - tigervnc11-xorg18.patch merged + - xserver18.patch is no longer needed + +* Wed Jan 27 2010 Jan Gorig 1.0.90-0.5.20091221svn3929 +- initscript LSB compliance fixes (#523974) + +* Fri Jan 22 2010 Adam Tkac 1.0.90-0.4.20091221svn3929 +- mark stack as non-executable in jpeg ASM code +- add xorg-x11-xauth to Requires +- add support for X.Org 1.8 +- drop shave sources, they are no longer needed + +* Thu Jan 21 2010 Adam Tkac 1.0.90-0.3.20091221svn3929 +- drop tigervnc-xorg25909.patch, it has been merged to X.Org upstream + +* Thu Jan 07 2010 Adam Tkac 1.0.90-0.2.20091221svn3929 +- add patch for upstream X.Org issue #25909 +- add libXdmcp-devel to build requires to build Xvnc with XDMCP support (#552322) + +* Mon Dec 21 2009 Adam Tkac 1.0.90-0.1.20091221svn3929 +- update to 1.0.90 snapshot +- patches merged + - tigervnc10-compat.patch + - tigervnc10-rh510185.patch + - tigervnc10-rh524340.patch + - tigervnc10-rh516274.patch + +* Mon Oct 26 2009 Adam Tkac 1.0.0-3 +- create Xvnc keyboard mapping before first keypress (#516274) + +* Thu Oct 08 2009 Adam Tkac 1.0.0-2 +- update underlying X source to 1.6.4-0.3.fc11 +- remove bogus '-nohttpd' parameter from /etc/sysconfig/vncservers (#525629) +- initscript LSB compliance fixes (#523974) +- improve -LowColorSwitch documentation and handling (#510185) +- honor dotWhenNoCursor option (and it's changes) every time (#524340) + +* Fri Aug 28 2009 Adam Tkac 1.0.0-1 +- update to 1.0.0 +- tigervnc10-rh495457.patch merged to upstream + +* Mon Aug 24 2009 Karsten Hopp 0.0.91-0.17 +- fix ifnarch s390x for server-module + +* Fri Aug 21 2009 Tomas Mraz - 0.0.91-0.16 +- rebuilt with new openssl + +* Tue Aug 04 2009 Adam Tkac 0.0.91-0.15 +- make Xvnc compilable + +* Sun Jul 26 2009 Fedora Release Engineering - 0.0.91-0.14.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jul 13 2009 Adam Tkac 0.0.91-0.13.1 +- don't write warning when initscript is called with condrestart param (#508367) + +* Tue Jun 23 2009 Adam Tkac 0.0.91-0.13 +- temporary use F11 Xserver base to make Xvnc compilable +- BuildRequires: libXi-devel +- don't ship tigervnc-server-module on s390/s390x + +* Mon Jun 22 2009 Adam Tkac 0.0.91-0.12 +- fix local rendering of cursor (#495457) + +* Thu Jun 18 2009 Adam Tkac 0.0.91-0.11 +- update to 0.0.91 (1.0.0 RC1) +- patches merged + - tigervnc10-rh499401.patch + - tigervnc10-rh497592.patch + - tigervnc10-rh501832.patch +- after discusion in upstream drop tigervnc-bounds.patch +- configure flags cleanup + +* Thu May 21 2009 Adam Tkac 0.0.90-0.10 +- rebuild against 1.6.1.901 X server (#497835) +- disable i18n, vncviewer is not UTF-8 compatible (#501832) + +* Mon May 18 2009 Adam Tkac 0.0.90-0.9 +- fix vncpasswd crash on long passwords (#499401) +- start session dbus daemon correctly (#497592) + +* Mon May 11 2009 Adam Tkac 0.0.90-0.8.1 +- remove merged tigervnc-manminor.patch + +* Tue May 05 2009 Adam Tkac 0.0.90-0.8 +- update to 0.0.90 + +* Thu Apr 30 2009 Adam Tkac 0.0.90-0.7.20090427svn3789 +- server package now requires xorg-x11-fonts-misc (#498184) + +* Mon Apr 27 2009 Adam Tkac 0.0.90-0.6.20090427svn3789 +- update to r3789 + - tigervnc-rh494801.patch merged +- tigervnc-newfbsize.patch is no longer needed +- fix problems when vncviewer and Xvnc run on different endianess (#496653) +- UltraVNC and TightVNC clients work fine again (#496786) + +* Wed Apr 08 2009 Adam Tkac 0.0.90-0.5.20090403svn3751 +- workaround broken fontpath handling in vncserver script (#494801) + +* Fri Apr 03 2009 Adam Tkac 0.0.90-0.4.20090403svn3751 +- update to r3751 +- patches merged + - tigervnc-xclients.patch + - tigervnc-clipboard.patch + - tigervnc-rh212985.patch +- basic RandR support in Xvnc (resize of the desktop) +- use built-in libjpeg (SSE2/MMX accelerated encoding on x86 platform) +- use Tight encoding by default +- use TigerVNC icons + +* Tue Mar 03 2009 Adam Tkac 0.0.90-0.3.20090303svn3631 +- update to r3631 + +* Tue Mar 03 2009 Adam Tkac 0.0.90-0.2.20090302svn3621 +- package review related fixes + +* Mon Mar 02 2009 Adam Tkac 0.0.90-0.1.20090302svn3621 +- initial package, r3621