import tigervnc-1.9.0-14.el8_1
This commit is contained in:
commit
8215c2e14f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/tigervnc-1.9.0.tar.gz
|
1
.tigervnc.metadata
Normal file
1
.tigervnc.metadata
Normal file
@ -0,0 +1 @@
|
||||
c56656c596fb863bb2c4b67fb62b4165011d181f SOURCES/tigervnc-1.9.0.tar.gz
|
28
SOURCES/0001-rpath-hack.patch
Normal file
28
SOURCES/0001-rpath-hack.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 2489f2f38eb32d9dd03718a36cbdbdf13d2f8b9b Mon Sep 17 00:00:00 2001
|
||||
From: Adam Jackson <ajax@redhat.com>
|
||||
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
|
||||
|
19
SOURCES/10-libvnc.conf
Normal file
19
SOURCES/10-libvnc.conf
Normal file
@ -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
|
74
SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch
Normal file
74
SOURCES/tigervnc-1.3.1-CVE-2014-8240.patch
Normal file
@ -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);
|
@ -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();
|
116
SOURCES/tigervnc-CVE-2019-15691.patch
Normal file
116
SOURCES/tigervnc-CVE-2019-15691.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From d61a767d6842b530ffb532ddd5a3d233119aad40 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
Date: Tue, 10 Sep 2019 11:05:48 +0200
|
||||
Subject: [PATCH] Make ZlibInStream more robust against failures
|
||||
|
||||
Move the checks around to avoid missing cases where we might access
|
||||
memory that is no longer valid. Also avoid touching the underlying
|
||||
stream implicitly (e.g. via the destructor) as it might also no
|
||||
longer be valid.
|
||||
|
||||
A malicious server could theoretically use this for remote code
|
||||
execution in the client.
|
||||
|
||||
Issue found by Pavel Cheremushkin from Kaspersky Lab
|
||||
---
|
||||
common/rdr/ZlibInStream.cxx | 13 +++++++------
|
||||
common/rdr/ZlibInStream.h | 2 +-
|
||||
common/rfb/CMsgReader.cxx | 3 ++-
|
||||
common/rfb/SMsgReader.cxx | 3 ++-
|
||||
common/rfb/TightDecoder.cxx | 3 ++-
|
||||
common/rfb/zrleDecode.h | 3 ++-
|
||||
6 files changed, 16 insertions(+), 11 deletions(-)
|
||||
|
||||
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
|
71
SOURCES/tigervnc-CVE-2019-15692.patch
Normal file
71
SOURCES/tigervnc-CVE-2019-15692.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 996356b6c65ca165ee1ea46a571c32a1dc3c3821 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
Date: Tue, 10 Sep 2019 15:21:03 +0200
|
||||
Subject: [PATCH] Restrict PixelBuffer dimensions to safe values
|
||||
|
||||
We do a lot of calculations based on pixel coordinates and we need
|
||||
to make sure they do not overflow. Restrict the maximum dimensions
|
||||
we support rather than try to switch over all calculations to use
|
||||
64 bit integers.
|
||||
|
||||
This prevents attackers from 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_;
|
75
SOURCES/tigervnc-CVE-2019-15693.patch
Normal file
75
SOURCES/tigervnc-CVE-2019-15693.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From b4ada8d0c6dac98c8b91fc64d112569a8ae5fb95 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
Date: Tue, 10 Sep 2019 15:36:42 +0200
|
||||
Subject: [PATCH] Handle empty Tight gradient rects
|
||||
|
||||
We always assumed there would be one pixel per row so a rect with
|
||||
a zero width would result in us writing to unknown memory.
|
||||
|
||||
This could theoretically be used by a malicious server to inject
|
||||
code in to the viewer process.
|
||||
|
||||
Issue found by Pavel Cheremushkin from Kaspersky Lab.
|
||||
---
|
||||
common/rfb/tightDecode.h | 37 +++++++++++++++++++++----------------
|
||||
1 file changed, 21 insertions(+), 16 deletions(-)
|
||||
|
||||
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) {
|
1419
SOURCES/tigervnc-CVE-2019-15694.patch
Normal file
1419
SOURCES/tigervnc-CVE-2019-15694.patch
Normal file
File diff suppressed because it is too large
Load Diff
17
SOURCES/tigervnc-CVE-2019-15695.patch
Normal file
17
SOURCES/tigervnc-CVE-2019-15695.patch
Normal file
@ -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;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
From 9f615301aba1cc54a749950bf9462c5a85217bc4 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
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 <rfb/SMsgWriter.h>
|
||||
#include <rfb/UpdateTracker.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
+#include <rfb/Exception.h>
|
||||
|
||||
#include <rfb/RawEncoder.h>
|
||||
#include <rfb/RREEncoder.h>
|
||||
@@ -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;
|
@ -0,0 +1,355 @@
|
||||
From 75e6e0653a48baf474fd45d78b1da53e2f324642 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
Date: Tue, 24 Sep 2019 09:41:07 +0200
|
||||
Subject: [PATCH] Be defensive about overflows in stream objects
|
||||
|
||||
We use a lot of lengths given to us over the network, so be more
|
||||
paranoid about them causing an overflow as otherwise an attacker
|
||||
might trick us in to overwriting other memory.
|
||||
|
||||
This primarily affects the client which often gets lengths from the
|
||||
server, but there are also some scenarios where the server might
|
||||
theoretically be vulnerable.
|
||||
|
||||
Issue found by Pavel Cheremushkin from Kaspersky Lab.
|
||||
---
|
||||
common/rdr/FdInStream.cxx | 8 +++++---
|
||||
common/rdr/FdOutStream.cxx | 7 ++++---
|
||||
common/rdr/FileInStream.cxx | 8 +++++---
|
||||
common/rdr/HexInStream.cxx | 8 +++++---
|
||||
common/rdr/HexOutStream.cxx | 6 ++++--
|
||||
common/rdr/InStream.h | 24 +++++++++++++-----------
|
||||
common/rdr/MemOutStream.h | 4 ++++
|
||||
common/rdr/OutStream.h | 24 +++++++++++++-----------
|
||||
common/rdr/RandomStream.cxx | 6 ++++--
|
||||
common/rdr/TLSInStream.cxx | 10 ++++++----
|
||||
common/rdr/TLSOutStream.cxx | 6 ++++--
|
||||
common/rdr/ZlibInStream.cxx | 6 ++++--
|
||||
common/rdr/ZlibOutStream.cxx | 6 ++++--
|
||||
13 files changed, 75 insertions(+), 48 deletions(-)
|
||||
|
||||
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 <rdr/Exception.h>
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
@@ -65,6 +66,9 @@ namespace rdr {
|
||||
if (len < (size_t)(end - start) * 2)
|
||||
len = (end - start) * 2;
|
||||
|
||||
+ if (len < (size_t)(end - start))
|
||||
+ throw Exception("Overflow in MemOutStream::overrun()");
|
||||
+
|
||||
U8* newStart = new U8[len];
|
||||
memcpy(newStart, start, ptr - start);
|
||||
ptr = newStart + (ptr - start);
|
||||
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;
|
||||
}
|
312
SOURCES/tigervnc-covscan.patch
Normal file
312
SOURCES/tigervnc-covscan.patch
Normal file
@ -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 <list>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <vector>
|
||||
#include <rfb/util.h>
|
||||
|
||||
std::list<TXWindow*> 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<bool> 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<bool> shared;
|
||||
+ std::vector<bool> 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;
|
12
SOURCES/tigervnc-cursor.patch
Normal file
12
SOURCES/tigervnc-cursor.patch
Normal file
@ -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);
|
||||
}
|
||||
|
526
SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch
Normal file
526
SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From 53f913a76196c7357d4858bfbf2c33caa9181bae Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
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<rfb::Rect> 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<network::SocketListener*> listeners;
|
||||
std::list<network::SocketListener*> 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;
|
||||
|
88
SOURCES/tigervnc-getmaster.patch
Normal file
88
SOURCES/tigervnc-getmaster.patch
Normal file
@ -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)
|
@ -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");
|
28
SOURCES/tigervnc-manpages.patch
Normal file
28
SOURCES/tigervnc-manpages.patch
Normal file
@ -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 <width>x<height>]\n".
|
||||
" [-pixelformat rgbNNN|bgrNNN]\n".
|
||||
" [-fp <font-path>]\n".
|
||||
+ " [-cc <visual>]\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 -<param> or off with -<param>=0\n"
|
||||
"Parameters which take a value can be specified as "
|
13
SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch
Normal file
13
SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch
Normal file
@ -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;
|
32
SOURCES/tigervnc-pixelformat-sanity-checks.patch
Normal file
32
SOURCES/tigervnc-pixelformat-sanity-checks.patch
Normal file
@ -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;
|
9
SOURCES/tigervnc-shebang.patch
Normal file
9
SOURCES/tigervnc-shebang.patch
Normal file
@ -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.
|
13
SOURCES/tigervnc-utilize-system-crypto-policies.patch
Normal file
13
SOURCES/tigervnc-utilize-system-crypto-policies.patch
Normal file
@ -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()
|
@ -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;
|
||||
}
|
||||
|
||||
|
13
SOURCES/tigervnc-working-tls-on-fips-systems.patch
Normal file
13
SOURCES/tigervnc-working-tls-on-fips-systems.patch
Normal file
@ -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) {
|
91
SOURCES/tigervnc-xserver120.patch
Normal file
91
SOURCES/tigervnc-xserver120.patch
Normal file
@ -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);
|
40
SOURCES/tigervnc-xstartup.patch
Normal file
40
SOURCES/tigervnc-xstartup.patch
Normal file
@ -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".
|
45
SOURCES/vncserver-system.service
Normal file
45
SOURCES/vncserver-system.service
Normal file
@ -0,0 +1,45 @@
|
||||
# The vncserver service unit file
|
||||
#
|
||||
# Quick HowTo:
|
||||
# 1. Copy this file to /etc/systemd/system/vncserver@.service
|
||||
# 2. Replace <USER> 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@:<display>.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 <USER> %i
|
||||
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
59
SOURCES/vncserver-user.service
Normal file
59
SOURCES/vncserver-user.service
Normal file
@ -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@:<display>.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
|
1
SOURCES/vncserver.sysconfig
Normal file
1
SOURCES/vncserver.sysconfig
Normal file
@ -0,0 +1 @@
|
||||
# THIS FILE HAS BEEN REPLACED BY /lib/systemd/system/vncserver@.service
|
42
SOURCES/vncserver_wrapper
Executable file
42
SOURCES/vncserver_wrapper
Executable file
@ -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 ..."
|
38
SOURCES/xvnc.service
Normal file
38
SOURCES/xvnc.service
Normal file
@ -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
|
9
SOURCES/xvnc.socket
Normal file
9
SOURCES/xvnc.socket
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=XVNC Server
|
||||
|
||||
[Socket]
|
||||
ListenStream=5900
|
||||
Accept=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
1060
SPECS/tigervnc.spec
Normal file
1060
SPECS/tigervnc.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user