Update to 1.7.90

This commit is contained in:
Jan Grulich 2017-04-20 10:54:57 +02:00
parent 2a8c8c1415
commit ce72cb5819
14 changed files with 7 additions and 850 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ tigervnc-1.0.90-20100721svn4113.tar.bz2
/tigervnc-1.6.90.tar.gz
/tigervnc-1.7.0.tar.gz
/tigervnc-1.7.1.tar.gz
/tigervnc-1.7.90.tar.gz

View File

@ -1,38 +0,0 @@
From 372ff9d6754cd1b375836e5d4559061fb7be3496 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 9 Jan 2017 16:03:30 +0100
Subject: [PATCH] Fix -inetd not working with xserver >= 1.19
xserver 1.19's OsInit will create a pollfd, followed by checking if fd 2 /
stderr is writable and if it is not, replacing fd 2 with /dev/null.
Since we close stderr in inetd mode to avoid xserver messages being send
to the client as vnc data, the pollfd becomes fd 2, only to be replaced
by /dev/null since a pollfd is not writable.
This commit fixes this by opening /dev/null directly after the close(2),
avoiding that the pollfd becomes fd 2.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
unix/xserver/hw/vnc/xvnc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c
index 2f3cd4a..a747654 100644
--- a/unix/xserver/hw/vnc/xvnc.c
+++ b/unix/xserver/hw/vnc/xvnc.c
@@ -575,6 +575,10 @@ ddxProcessArgument(int argc, char *argv[], int i)
dup2(0,3);
vncInetdSock = 3;
close(2);
+ /* Avoid xserver >= 1.19's epoll-fd becoming fd 2 / stderr only to be
+ replaced by /dev/null by OsInit() because the pollfd is not
+ writable, breaking ospoll_wait(). */
+ open("/dev/null", O_WRONLY);
if (!displaySpecified) {
int port = vncGetSocketPort(vncInetdSock);
--
2.9.3

View File

@ -1 +1 @@
SHA512 (tigervnc-1.7.1.tar.gz) = babdc362b28d7af80c7efbb3a1aadf158d7f29621afe36d785748af45e515e2718cf1011359db7b39c218770b3f3ee2767e08abc58091f018c08ba9739a3e68d
SHA512 (tigervnc-1.7.90.tar.gz) = 8c4b78538658fc1b1f485c4fc01c35eb6487fba6947b27ea76f89d5a7c4fbeac150c8bb22393c223fdae82bf95be73461118cf1cab93e210cbbcabcd38393afb

View File

@ -1,422 +0,0 @@
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c 2016-10-04 17:17:35.618889747 +0200
@@ -30,6 +30,23 @@
#include "vncExtInit.h"
#include "vncBlockHandler.h"
+#include "xorg-version.h"
+
+#if XORG >= 119
+
+static void vncBlockHandler(void* data, void* timeout)
+{
+ vncCallBlockHandlers(timeout);
+}
+
+void vncRegisterBlockHandlers(void)
+{
+ if (!RegisterBlockAndWakeupHandlers(vncBlockHandler,
+ (ServerWakeupHandlerProcPtr)NoopDDA, 0))
+ FatalError("RegisterBlockAndWakeupHandlers() failed\n");
+}
+
+#else
static void vncBlockHandler(void * data, OSTimePtr t, void * readmask);
static void vncWakeupHandler(void * data, int nfds, void * readmask);
@@ -144,3 +161,5 @@ static void vncWriteWakeupHandlerFallbac
vncWriteWakeupHandler(ret, &fallbackFds);
}
+
+#endif
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc 2016-10-04 17:17:35.618889747 +0200
@@ -241,6 +241,17 @@ int vncExtensionIsActive(int scrIdx)
return (desktop[scrIdx] != NULL);
}
+#if XORG >= 119
+
+void vncCallBlockHandlers(int* timeout)
+{
+ for (int scr = 0; scr < vncGetScreenCount(); scr++)
+ if (desktop[scr])
+ desktop[scr]->blockHandler(timeout);
+}
+
+#else
+
void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout)
{
for (int scr = 0; scr < vncGetScreenCount(); scr++)
@@ -269,6 +280,8 @@ void vncCallWriteWakeupHandlers(fd_set *
desktop[scr]->writeWakeupHandler(fds, nfds);
}
+#endif
+
int vncGetAvoidShiftNumLock(void)
{
return (bool)avoidShiftNumLock;
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h 2016-10-04 17:17:35.618889747 +0200
@@ -22,6 +22,7 @@
#include <stdint.h>
#include <stddef.h>
#include <sys/select.h>
+#include "xorg-version.h"
// Only from C++
#ifdef __cplusplus
@@ -52,10 +53,14 @@ extern int vncInetdSock;
void vncExtensionInit(void);
int vncExtensionIsActive(int scrIdx);
+#if XORG >= 119
+void vncCallBlockHandlers(int* timeout);
+#else
void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout);
void vncCallReadWakeupHandlers(fd_set * fds, int nfds);
void vncCallWriteBlockHandlers(fd_set * fds, struct timeval ** timeout);
void vncCallWriteWakeupHandlers(fd_set * fds, int nfds);
+#endif
int vncGetAvoidShiftNumLock(void);
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c 2016-10-04 17:17:35.618889747 +0200
@@ -128,9 +128,11 @@ static Bool vncHooksDisplayCursor(Device
#if XORG <= 112
static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
pointer pReadmask);
-#else
+#elif XORG <= 118
static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout,
void * pReadmask);
+#else
+static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout);
#endif
#ifdef RENDER
static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
@@ -716,9 +718,11 @@ out:
#if XORG <= 112
static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
pointer pReadmask)
-#else
+#elif XORG <= 118
static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout,
void * pReadmask)
+#else
+static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
#endif
{
#if XORG <= 112
@@ -731,8 +735,10 @@ static void vncHooksBlockHandler(ScreenP
#if XORG <= 112
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-#else
+#elif XORG <= 118
(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
+#else
+ (*pScreen->BlockHandler) (pScreen, pTimeout);
#endif
vncHooksScreen->ignoreHooks--;
@@ -1033,12 +1039,21 @@ static void vncHooksCopyClip(GCPtr dst,
// Unwrap and rewrap helpers
+#if XORG >= 116
+#define GC_OP_PROLOGUE(pGC, name)\
+ vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
+ const GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->wrappedFuncs;\
+ pGC->ops = pGCPriv->wrappedOps; \
+ DBGPRINT((stderr,"vncHooks" #name " called\n"))
+#else
#define GC_OP_PROLOGUE(pGC, name)\
vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
GCFuncs *oldFuncs = pGC->funcs;\
pGC->funcs = pGCPriv->wrappedFuncs;\
pGC->ops = pGCPriv->wrappedOps; \
DBGPRINT((stderr,"vncHooks" #name " called\n"))
+#endif
#define GC_OP_EPILOGUE(pGC)\
pGCPriv->wrappedOps = pGC->ops;\
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h
--- tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h 2016-10-04 17:24:51.640654527 +0200
@@ -50,8 +50,10 @@
#define XORG 117
#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (18 * 100000) + (99 * 1000))
#define XORG 118
+#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (19 * 100000) + (99 * 1000))
+#define XORG 119
#else
-#error "X.Org newer than 1.18 is not supported"
+#error "X.Org newer than 1.19 is not supported"
#endif
#endif
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc
--- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc 2016-10-04 17:23:47.171977905 +0200
@@ -89,6 +89,30 @@ public:
XserverDesktop* desktop;
};
+#if XORG >= 119
+extern "C" {
+/*
+ * xserver NotifyFd callbacks. Note we also expect write notifies to work,
+ * which only works with xserver >= 1.19.
+ */
+#include "os.h"
+
+static void HandleListenFd(int fd, int xevents, void *data)
+{
+ XserverDesktop *desktop = (XserverDesktop *)data;
+
+ desktop->handleListenFd(fd);
+}
+
+static void HandleSocketFd(int fd, int xevents, void *data)
+{
+ XserverDesktop *desktop = (XserverDesktop *)data;
+
+ desktop->handleSocketFd(fd, xevents);
+}
+
+}
+#endif
XserverDesktop::XserverDesktop(int screenIndex_,
std::list<network::TcpListener*> listeners_,
@@ -110,15 +134,35 @@ XserverDesktop::XserverDesktop(int scree
if (!httpListeners.empty ())
httpServer = new FileHTTPServer(this);
+
+#if XORG >= 119
+ for (std::list<TcpListener*>::iterator i = listeners.begin();
+ i != listeners.end();
+ i++) {
+ SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
+ }
+
+ for (std::list<TcpListener*>::iterator i = httpListeners.begin();
+ i != httpListeners.end();
+ i++) {
+ SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
+ }
+#endif
}
XserverDesktop::~XserverDesktop()
{
while (!listeners.empty()) {
+#if XORG >= 119
+ RemoveNotifyFd(listeners.back()->getFd());
+#endif
delete listeners.back();
listeners.pop_back();
}
while (!httpListeners.empty()) {
+#if XORG >= 119
+ RemoveNotifyFd(listeners.back()->getFd());
+#endif
delete httpListeners.back();
httpListeners.pop_back();
}
@@ -388,6 +432,140 @@ void XserverDesktop::add_copied(const rf
}
}
+#if XORG >= 119
+void XserverDesktop::handleListenFd(int fd)
+{
+ std::list<TcpListener*>::iterator i;
+ SocketServer *fd_server = NULL;
+ bool is_http = false;
+
+ for (i = listeners.begin(); i != listeners.end(); i++) {
+ if ((*i)->getFd() == fd) {
+ fd_server = server;
+ break;
+ }
+ }
+ if (httpServer && !fd_server) {
+ for (i = httpListeners.begin(); i != httpListeners.end(); i++) {
+ if ((*i)->getFd() == fd) {
+ fd_server = httpServer;
+ is_http = true;
+ break;
+ }
+ }
+ }
+ if (!fd_server) {
+ vlog.error("XserverDesktop::handleListenFd: Error cannot find fd");
+ return;
+ }
+
+ Socket* sock = (*i)->accept();
+ sock->outStream().setBlocking(false);
+ vlog.debug("new %sclient, sock %d", is_http ? "http " : "", sock->getFd());
+ fd_server->addSocket(sock);
+ SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
+}
+
+void XserverDesktop::handleSocketFd(int fd, int xevents)
+{
+ std::list<Socket*> sockets;
+ std::list<Socket*>::iterator i;
+ SocketServer *fd_server = NULL;
+ bool is_http = false;
+
+ server->getSockets(&sockets);
+ for (i = sockets.begin(); i != sockets.end(); i++) {
+ if ((*i)->getFd() == fd) {
+ fd_server = server;
+ break;
+ }
+ }
+ if (httpServer && !fd_server) {
+ httpServer->getSockets(&sockets);
+ for (i = sockets.begin(); i != sockets.end(); i++) {
+ if ((*i)->getFd() == fd) {
+ fd_server = httpServer;
+ is_http = true;
+ break;
+ }
+ }
+ }
+ if (!fd_server) {
+ vlog.error("XserverDesktop::handleSocketFd: Error cannot find fd");
+ return;
+ }
+
+ if (xevents & X_NOTIFY_READ)
+ fd_server->processSocketReadEvent(*i);
+
+ if (xevents & X_NOTIFY_WRITE)
+ fd_server->processSocketWriteEvent(*i);
+
+ if ((*i)->isShutdown()) {
+ vlog.debug("%sclient gone, sock %d", is_http ? "http " : "", fd);
+ RemoveNotifyFd(fd);
+ fd_server->removeSocket(*i);
+ if (!is_http)
+ vncClientGone(fd);
+ delete (*i);
+ }
+}
+
+void XserverDesktop::blockHandler(int* timeout)
+{
+ // We don't have a good callback for when we can init input devices[1],
+ // so we abuse the fact that this routine will be called first thing
+ // once the dix is done initialising.
+ // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing.
+ vncInitInputDevice();
+
+ try {
+ std::list<Socket*> sockets;
+ std::list<Socket*>::iterator i;
+ server->getSockets(&sockets);
+ for (i = sockets.begin(); i != sockets.end(); i++) {
+ int fd = (*i)->getFd();
+ if ((*i)->isShutdown()) {
+ vlog.debug("client gone, sock %d",fd);
+ server->removeSocket(*i);
+ vncClientGone(fd);
+ delete (*i);
+ } else {
+ /* Update existing NotifyFD to listen for write (or not) */
+ if ((*i)->outStream().bufferUsage() > 0)
+ SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
+ else
+ SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
+ }
+ }
+ if (httpServer) {
+ httpServer->getSockets(&sockets);
+ for (i = sockets.begin(); i != sockets.end(); i++) {
+ int fd = (*i)->getFd();
+ if ((*i)->isShutdown()) {
+ vlog.debug("http client gone, sock %d",fd);
+ httpServer->removeSocket(*i);
+ delete (*i);
+ } else {
+ /* Update existing NotifyFD to listen for write (or not) */
+ if ((*i)->outStream().bufferUsage() > 0)
+ SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
+ else
+ SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
+ }
+ }
+ }
+
+ int nextTimeout = server->checkTimeouts();
+ if (nextTimeout > 0 && (*timeout == -1 || nextTimeout < *timeout))
+ *timeout = nextTimeout;
+ } catch (rdr::Exception& e) {
+ vlog.error("XserverDesktop::blockHandler: %s",e.str());
+ }
+}
+
+#else
+
void XserverDesktop::readBlockHandler(fd_set* fds, struct timeval ** timeout)
{
// We don't have a good callback for when we can init input devices[1],
@@ -600,10 +778,15 @@ void XserverDesktop::writeWakeupHandler(
}
}
+#endif
+
void XserverDesktop::addClient(Socket* sock, bool reverse)
{
vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
server->addSocket(sock, reverse);
+#if XORG >= 119
+ SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
+#endif
}
void XserverDesktop::disconnectClients()
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h
--- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119 2016-09-08 12:31:18.000000000 +0200
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h 2016-10-04 17:17:35.617889712 +0200
@@ -38,6 +38,7 @@
#include <rfb/VNCServerST.h>
#include <rdr/SubstitutingInStream.h>
#include "Input.h"
+#include "xorg-version.h"
namespace rfb {
class VNCServerST;
@@ -69,10 +70,16 @@ public:
const unsigned char *rgbaData);
void add_changed(const rfb::Region &region);
void add_copied(const rfb::Region &dest, const rfb::Point &delta);
+#if XORG >= 119
+ void handleListenFd(int fd);
+ void handleSocketFd(int fd, int xevents);
+ void blockHandler(int* timeout);
+#else
void readBlockHandler(fd_set* fds, struct timeval ** timeout);
void readWakeupHandler(fd_set* fds, int nfds);
void writeBlockHandler(fd_set* fds, struct timeval ** timeout);
void writeWakeupHandler(fd_set* fds, int nfds);
+#endif
void addClient(network::Socket* sock, bool reverse);
void disconnectClients();

View File

@ -1,20 +0,0 @@
From fbbd48b35e53fb156b91715dae4aab9008533565 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
Date: Wed, 29 Mar 2017 13:27:32 +0200
Subject: Avoid leaking shared memory via X server
It's not enough that we detach from the shared memory, we must also
tell the X server to do so for it to be freed properly.
diff --git a/vncviewer/X11PixelBuffer.cxx b/vncviewer/X11PixelBuffer.cxx
index ce5c4d8..ac35dfc 100644
--- a/vncviewer/X11PixelBuffer.cxx
+++ b/vncviewer/X11PixelBuffer.cxx
@@ -126,6 +126,7 @@ X11PixelBuffer::~X11PixelBuffer()
{
if (shminfo) {
vlog.debug("Freeing shared memory XImage");
+ XShmDetach(fl_display, shminfo);
shmList.remove(this);
Fl::remove_system_handler(handleSystemEvent);
shmdt(shminfo->shmaddr);

View File

@ -1,20 +0,0 @@
From d71508b94bd1c6f0d8be89aa559a8a7de48f7f3f Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
Date: Wed, 29 Mar 2017 13:28:55 +0200
Subject: Be more restrictive with shared memory mode bits
Everyone else seems to get by with using 0600, so let's do the same.
diff --git a/vncviewer/X11PixelBuffer.cxx b/vncviewer/X11PixelBuffer.cxx
index ce5c4d8..a1673da 100644
--- a/vncviewer/X11PixelBuffer.cxx
+++ b/vncviewer/X11PixelBuffer.cxx
@@ -189,7 +190,7 @@ int X11PixelBuffer::setupShm()
shminfo->shmid = shmget(IPC_PRIVATE,
xim->bytes_per_line * xim->height,
- IPC_CREAT|0777);
+ IPC_CREAT|0600);
if (shminfo->shmid == -1)
goto free_xim;

View File

@ -1,20 +0,0 @@
From 8f3e8663b3cf57c0b62d939d6953fbfcc112aadd Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Wed, 29 Mar 2017 16:23:18 +0300
Subject: Delete underlying ssecurity in SSecurityVeNCrypt.
Otherwise it gets leaked which would allow even not authenticated clients to exhaust server memory.
diff --git a/common/rfb/SSecurityVeNCrypt.cxx b/common/rfb/SSecurityVeNCrypt.cxx
index 7c13749..ce6c71b 100644
--- a/common/rfb/SSecurityVeNCrypt.cxx
+++ b/common/rfb/SSecurityVeNCrypt.cxx
@@ -55,6 +55,8 @@ SSecurityVeNCrypt::SSecurityVeNCrypt(SecurityServer *sec) : security(sec)
SSecurityVeNCrypt::~SSecurityVeNCrypt()
{
+ delete ssecurity;
+
if (subTypes) {
delete [] subTypes;
subTypes = NULL;

View File

@ -1,23 +0,0 @@
From 9801c5efcf8c1774d9c807ebd5d27ac7049ad993 Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Wed, 29 Mar 2017 17:00:30 +0300
Subject: Fix checkNoWait logic in SSecurityPlain.
Currently it proceeds only if there aren't enough data in queue and then it blocks waiting.
Also the required amount to receive from network is (ulen + plen), not (ulen + plen + 2).
This allowed not authenticated clients to deny service to everyone.
diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx
index f5a5cc7..0531549 100644
--- a/common/rfb/SSecurityPlain.cxx
+++ b/common/rfb/SSecurityPlain.cxx
@@ -92,7 +92,7 @@ bool SSecurityPlain::processMsg(SConnection* sc)
}
if (state == 1) {
- if (is->checkNoWait(ulen + plen + 2))
+ if (!is->checkNoWait(ulen + plen))
return false;
state = 2;
pw = new char[plen + 1];

View File

@ -1,23 +0,0 @@
From bf3bdac082978ca32895a4b6a123016094905689 Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Mon, 27 Mar 2017 13:37:11 +0300
Subject: Fix crash from integer overflow in SMsgReader::readClientCutText
The length sent by client is U32, but is converted into int. If it was bigger than 0x7fffffff the resulting int is negative, it passes the check against maxCutText and later throws std::bad_alloc from CharArray which takes down the whole server.
All the Streaming API deals with lengths in ints, so we can't tell it to skip that big amount of data. And it is not realistic to expect more than 2GB of clipboard data anyway. So lets just throw rdr::Exception that will disconnect this client and keep the server alive.
diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx
index 89c9a8f..3c08fd6 100644
--- a/common/rfb/SMsgReader.cxx
+++ b/common/rfb/SMsgReader.cxx
@@ -200,6 +200,9 @@ void SMsgReader::readClientCutText()
{
is->skip(3);
int len = is->readU32();
+ if (len < 0) {
+ throw Exception("Cut text too long.");
+ }
if (len > maxCutText) {
is->skip(len);
vlog.error("Cut text too long (%d bytes) - ignoring", len);

View File

@ -1,20 +0,0 @@
diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am
index d7ab259..fb477c5 100644
--- a/unix/xserver/hw/vnc/Makefile.am
+++ b/unix/xserver/hw/vnc/Makefile.am
@@ -5,6 +5,7 @@ RFB_LIB=$(LIB_DIR)/rfb/librfb.la
RDR_LIB=$(LIB_DIR)/rdr/librdr.la
NETWORK_LIB=$(LIB_DIR)/network/libnetwork.la
XREGION_LIB=$(LIB_DIR)/Xregion/libXregion.la
+OS_LIB=$(LIB_DIR)/os/libos.la
COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(XREGION_LIB)
noinst_LTLIBRARIES = libvnccommon.la
@@ -64,6 +65,6 @@ libvnc_la_CPPFLAGS = $(XVNC_CPPFLAGS) -I$(TIGERVNC_SRCDIR)/common -UHAVE_CONFIG_
libvnc_la_LDFLAGS = -module -avoid-version -Wl,-z,now
-libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS)
+libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) $(OS_LIB)
EXTRA_DIST = Xvnc.man

View File

@ -1,48 +0,0 @@
From 62197c89e98be47a174074e4c7429c57767a4929 Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Wed, 29 Mar 2017 17:05:45 +0300
Subject: Limit max username/password size in SSecurityPlain.
Setting the limit to 1024 which should be still more than enough.
Unlimited ulen and plen can cause various security problems:
* Overflow in `is->checkNoWait(ulen + plen)` causing it to contine when there is not enough data and then wait forever.
* Overflow in `new char[plen + 1]` that would allocate zero sized array which succeeds but returns pointer that should not be written into.
* Allocation failure in `new char[plen + 1]` from trying to allocate too much and crashing the whole server.
All those issues can be triggered by a client before authentication.
diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx
index 0531549..fc9dff2 100644
--- a/common/rfb/SSecurityPlain.cxx
+++ b/common/rfb/SSecurityPlain.cxx
@@ -86,8 +86,15 @@ bool SSecurityPlain::processMsg(SConnection* sc)
if (state == 0) {
if (!is->checkNoWait(8))
return false;
+
ulen = is->readU32();
+ if (ulen > MaxSaneUsernameLength)
+ throw AuthFailureException("Too long username");
+
plen = is->readU32();
+ if (plen > MaxSanePasswordLength)
+ throw AuthFailureException("Too long password");
+
state = 1;
}
diff --git a/common/rfb/SSecurityPlain.h b/common/rfb/SSecurityPlain.h
index 080fcd5..2c08c24 100644
--- a/common/rfb/SSecurityPlain.h
+++ b/common/rfb/SSecurityPlain.h
@@ -54,6 +54,9 @@ namespace rfb {
PasswordValidator* valid;
unsigned int ulen, plen, state;
CharArray username;
+
+ static const unsigned int MaxSaneUsernameLength = 1024;
+ static const unsigned int MaxSanePasswordLength = 1024;
};
}

View File

@ -1,34 +0,0 @@
From f3afa24da144409a3c3a0e35913112583d987671 Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Mon, 27 Mar 2017 19:02:15 +0300
Subject: Prevent double free by crafted fences.
If client sent fence with some data, followed by fence with no data (length 0), the original fence data were freed, but the pointer kept pointing at them. Sending one more fence would attempt to free them again.
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index cf3264e..bc3f439 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -101,7 +101,9 @@ void SMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
os->writeU32(flags);
os->writeU8(len);
- os->writeBytes(data, len);
+
+ if (len > 0)
+ os->writeBytes(data, len);
endMsg();
}
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 0a2ca33..d2206f9 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -666,6 +666,7 @@ void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
fenceFlags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter | fenceFlagSyncNext);
fenceDataLen = len;
delete [] fenceData;
+ fenceData = NULL;
if (len > 0) {
fenceData = new char[len];
memcpy(fenceData, data, len);

View File

@ -1,139 +0,0 @@
From dccb5f7d776e93863ae10bbff56a45c523c6eeb0 Mon Sep 17 00:00:00 2001
From: Michal Srb <michalsrb@gmail.com>
Date: Mon, 27 Mar 2017 13:55:46 +0300
Subject: Prevent leak of SecurityServer and ClientServer.
They are created in SConnection's and CConnection's constructors but never destroyed.
There is no reason for the indirection, so lets make them direct members.
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx
index 2020418..88befd5 100644
--- a/common/rfb/CConnection.cxx
+++ b/common/rfb/CConnection.cxx
@@ -44,7 +44,6 @@ CConnection::CConnection()
state_(RFBSTATE_UNINITIALISED), useProtocol3_3(false),
framebuffer(NULL), decoder(this)
{
- security = new SecurityClient();
}
CConnection::~CConnection()
@@ -167,7 +166,7 @@ void CConnection::processSecurityTypesMsg()
int secType = secTypeInvalid;
std::list<rdr::U8> secTypes;
- secTypes = security->GetEnabledSecTypes();
+ secTypes = security.GetEnabledSecTypes();
if (cp.isVersion(3,3)) {
@@ -235,7 +234,7 @@ void CConnection::processSecurityTypesMsg()
}
state_ = RFBSTATE_SECURITY;
- csecurity = security->GetCSecurity(secType);
+ csecurity = security.GetCSecurity(secType);
processSecurityMsg();
}
diff --git a/common/rfb/CConnection.h b/common/rfb/CConnection.h
index 799a9c2..e0a000f 100644
--- a/common/rfb/CConnection.h
+++ b/common/rfb/CConnection.h
@@ -26,6 +26,7 @@
#include <rfb/CMsgHandler.h>
#include <rfb/DecodeManager.h>
+#include <rfb/SecurityClient.h>
#include <rfb/util.h>
namespace rfb {
@@ -34,7 +35,6 @@ namespace rfb {
class CMsgWriter;
class CSecurity;
class IdentityVerifier;
- class SecurityClient;
class CConnection : public CMsgHandler {
public:
@@ -148,7 +148,7 @@ namespace rfb {
stateEnum state() { return state_; }
CSecurity *csecurity;
- SecurityClient *security;
+ SecurityClient security;
protected:
void setState(stateEnum s) { state_ = s; }
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 17ef4d9..85cc6e8 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -51,7 +51,7 @@ const SConnection::AccessRights SConnection::AccessFull = 0xffff;
SConnection::SConnection()
: readyForSetColourMapEntries(false),
is(0), os(0), reader_(0), writer_(0),
- security(0), ssecurity(0), state_(RFBSTATE_UNINITIALISED),
+ ssecurity(0), state_(RFBSTATE_UNINITIALISED),
preferredEncoding(encodingRaw)
{
defaultMajorVersion = 3;
@@ -60,8 +60,6 @@ SConnection::SConnection()
defaultMinorVersion = 3;
cp.setVersion(defaultMajorVersion, defaultMinorVersion);
-
- security = new SecurityServer();
}
SConnection::~SConnection()
@@ -142,7 +140,7 @@ void SConnection::processVersionMsg()
std::list<rdr::U8> secTypes;
std::list<rdr::U8>::iterator i;
- secTypes = security->GetEnabledSecTypes();
+ secTypes = security.GetEnabledSecTypes();
if (cp.isVersion(3,3)) {
@@ -161,7 +159,7 @@ void SConnection::processVersionMsg()
os->writeU32(*i);
if (*i == secTypeNone) os->flush();
state_ = RFBSTATE_SECURITY;
- ssecurity = security->GetSSecurity(*i);
+ ssecurity = security.GetSSecurity(*i);
processSecurityMsg();
return;
}
@@ -193,7 +191,7 @@ void SConnection::processSecurityType(int secType)
std::list<rdr::U8> secTypes;
std::list<rdr::U8>::iterator i;
- secTypes = security->GetEnabledSecTypes();
+ secTypes = security.GetEnabledSecTypes();
for (i=secTypes.begin(); i!=secTypes.end(); i++)
if (*i == secType) break;
if (i == secTypes.end())
@@ -204,7 +202,7 @@ void SConnection::processSecurityType(int secType)
try {
state_ = RFBSTATE_SECURITY;
- ssecurity = security->GetSSecurity(secType);
+ ssecurity = security.GetSSecurity(secType);
} catch (rdr::Exception& e) {
throwConnFailedException(e.str());
}
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
index b43cf08..63dc314 100644
--- a/common/rfb/SConnection.h
+++ b/common/rfb/SConnection.h
@@ -196,7 +196,7 @@ namespace rfb {
rdr::OutStream* os;
SMsgReader* reader_;
SMsgWriter* writer_;
- SecurityServer *security;
+ SecurityServer security;
SSecurity* ssecurity;
stateEnum state_;
rdr::S32 preferredEncoding;

View File

@ -1,6 +1,6 @@
Name: tigervnc
Version: 1.7.1
Release: 4%{?dist}
Version: 1.7.90
Release: 1%{?dist}
Summary: A TigerVNC remote display system
%global _hardened_build 1
@ -50,32 +50,12 @@ Obsoletes: vnc < 4.1.3-2, vnc-libs < 4.1.3-2
Provides: tightvnc = 1.5.0-0.15.20090204svn3586
Obsoletes: tightvnc < 1.5.0-0.15.20090204svn3586
Patch1: tigervnc-1.7.0-xserver119-support.patch
Patch2: 0001-Fix-inetd-not-working-with-xserver-1.19.patch
Patch3: tigervnc-libvnc-os.patch
Patch7: tigervnc-manpages.patch
Patch8: tigervnc-getmaster.patch
Patch9: tigervnc-shebang.patch
Patch14: tigervnc-xstartup.patch
Patch18: tigervnc-utilize-system-crypto-policies.patch
# Upstream fixes for CVEs
# Bug 1438694 - (CVE-2017-7392) CVE-2017-7392 tigervnc: SSecurityVeNCrypt memory leak
Patch50: tigervnc-delete-underlying-ssecurity.patch
# Bug 1438697 - (CVE-2017-7393) CVE-2017-7393 tigervnc: Double free via crafted fences
Patch51: tigervnc-prevent-double-free-by-crafted-fences.patch
# Bug 1438700 - (CVE-2017-7394) CVE-2017-7394 tigervnc: Server crash via long filenames
Patch52: tigervnc-limit-max-username-password-size-in-ssecurityplain.patch
# Bug 1438701 - (CVE-2017-7395) CVE-2017-7395 tigervnc: Integer overflow in SMsgReader::readClientCutText
Patch53: tigervnc-fix-crash-from-integer-overflow.patch
# Bug 1438703 - (CVE-2017-7396) CVE-2017-7396 tigervnc: SecurityServer and ClientServer memory leaks
Patch54: tigervnc-prevent-leak-of-securityserver-and-clientserver.patch
# Other important fixes
Patch60: tigervnc-avoid-leaking-shared-memory.patch
Patch61: tigervnc-be-more-restrictive-with-shared-memory-mode-bits.patch
Patch62: tigervnc-fix-checknowait-logic-in-ssecurityplain.patch
# This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg
Patch100: tigervnc-xserver119.patch
@ -165,11 +145,6 @@ This package contains icons for TigerVNC viewer
%prep
%setup -q
%patch1 -p1 -b .xserver119
%if 0%{?fedora} > 24
%patch2 -p1 -b .inetd
%endif
%patch3 -p1 -b .libvnc-os
cp -r /usr/share/xorg-x11-server-source/* unix/xserver
pushd unix/xserver
@ -194,21 +169,6 @@ popd
# Utilize system-wide crypto policies
%patch18 -p1 -b .utilize-system-crypto-policies.patch
# Bug 1438694 - (CVE-2017-7392) CVE-2017-7392 tigervnc: SSecurityVeNCrypt memory leak
%patch50 -p1 -b .delete-underlying-ssecurity.patch
# Bug 1438697 - (CVE-2017-7393) CVE-2017-7393 tigervnc: Double free via crafted fences
%patch51 -p1 -b .prevent-double-free-by-crafted-fences.patch
# Bug 1438700 - (CVE-2017-7394) CVE-2017-7394 tigervnc: Server crash via long filenames
%patch52 -p1 -b .limit-max-username-password-size-in-ssecurityplain.patch
# Bug 1438701 - (CVE-2017-7395) CVE-2017-7395 tigervnc: Integer overflow in SMsgReader::readClientCutText
%patch53 -p1 -b .fix-crash-from-integer-overflow.patch
# Bug 1438703 - (CVE-2017-7396) CVE-2017-7396 tigervnc: SecurityServer and ClientServer memory leaks
%patch54 -p1 -b .prevent-leak-of-securityserver-and-clientserver.patch
# Other important fixes
%patch60 -p1 -b .avoid-leaking-shared-memory.patch
%patch61 -p1 -b .be-more-restrictive-with-shared-memory-mode-bits.patch
%patch62 -p1 -b .fix-checknowait-logic-in-ssecurityplain.patch
%build
%ifarch sparcv9 sparc64 s390 s390x
@ -371,6 +331,9 @@ fi
%{_datadir}/icons/hicolor/*/apps/*
%changelog
* Thu Apr 20 2017 Jan Grulich <jgrulich@redhat.com> - 1.7.90-1
- Update to 1.7.90 (beta)
* Thu Apr 06 2017 Jan Grulich <jgrulich@redhat.com> - 1.7.1-4
- Added systemd unit file for xvnc
Resolves: bz#891802