CVE-2019-15683: Out-of-bounds Write (CWE-787)
value: TurboVNC server code contains stack buffer overflow vulnerability in commit prior to cea98166008301e614e0d36776bf9435a536136e. This could possibly result into remote code execution, since stack frame is not protected with stack canary. This attack appear to be exploitable via network connectivity. To exploit this vulnerability authorization on server is required. These issues have been fixed in commit cea98166008301e614e0d36776bf9435a536136e.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 9.8
Published: 2019-10-29T19:15Z
Repository: https://github.com/TurboVNC/turbovnc
Language: C
Files changed: unix/Xvnc/programs/Xserver/hw/vnc/auth.c, unix/Xvnc/programs/Xserver/hw/vnc/rfbserver.c
Commit date: 2019-08-23 10:32:39 -0500
Commit message: Server: Fix two issues identified by ASan

1. If the TLSPlain and X509Plain security types were both disabled, then
   rfbOptPamAuth() would overflow the name field in the secTypes
   structure when testing the "none" security type, since the name of
   that security type has less than five characters.  This issue was
   innocuous, since the overflow was fully contained within the secTypes
   structure, but the ASan error caused Xvnc to abort, which made it
   difficult to detect other errors.

2. If an ill-behaved RFB client sent the TurboVNC Server a fence
   message with more than 64 bytes, then the TurboVNC Server would
   try to read that message and subsequently overflow the stack before
   it detected that the payload was too large.  This could never have
   occurred with any of the VNC viewers that currently support the RFB
   flow control extensions (TigerVNC and TurboVNC, namely.)  This issue
   was also innocuous, since the stack overflow affected two variables
   (newScreens and errMsg) that were never accessed before the function
   returned.

Diff: diff --git a/unix/Xvnc/programs/Xserver/hw/vnc/auth.c b/unix/Xvnc/programs/Xserver/hw/vnc/auth.c
index 2abc763c..801afbc9 100644
--- a/unix/Xvnc/programs/Xserver/hw/vnc/auth.c
+++ b/unix/Xvnc/programs/Xserver/hw/vnc/auth.c
@@ -391,11 +391,11 @@ Bool rfbOptPamAuth(void)
 {
   SecTypeData *s;
 
   for (s = secTypes; s->name != NULL; s++) {
     if ((!strcmp(s->name, "unixlogin") ||
-         !strcmp(&s->name[strlen(s->name) - 5], "plain")) && s->enabled)
+         strstr(s->name, "plain")) && s->enabled)
       return TRUE;
   }
 
   return FALSE;
 }
diff --git a/unix/Xvnc/programs/Xserver/hw/vnc/rfbserver.c b/unix/Xvnc/programs/Xserver/hw/vnc/rfbserver.c
index 03baa636..58b30666 100644
--- a/unix/Xvnc/programs/Xserver/hw/vnc/rfbserver.c
+++ b/unix/Xvnc/programs/Xserver/hw/vnc/rfbserver.c
@@ -1312,17 +1312,19 @@ static void rfbProcessClientNormalMessage(rfbClientPtr cl)
 
       READ(((char *)&msg) + 1, sz_rfbFenceMsg - 1)
 
       flags = Swap32IfLE(msg.f.flags);
 
-      READ(data, msg.f.length)
-
-      if (msg.f.length > sizeof(data))
+      if (msg.f.length > sizeof(data)) {
         rfbLog("Ignoring fence.  Payload of %d bytes is too large.\n",
                msg.f.length);
-      else
+        SKIP(msg.f.length)
+      } else {
+        READ(data, msg.f.length)
         HandleFence(cl, flags, msg.f.length, data);
+      }
+
       return;
     }
 
     #define EDSERROR(format, args...) {  \
       if (!strlen(errMsg))  \

Vulnerable code:          !strcmp(&s->name[strlen(s->name) - 5], "plain")) && s->enabled)
      READ(data, msg.f.length)

      if (msg.f.length > sizeof(data))
      else
Fixed code:          strstr(s->name, "plain")) && s->enabled)
      if (msg.f.length > sizeof(data)) {
        SKIP(msg.f.length)
      } else {
        READ(data, msg.f.length)
      }