CVE-2018-20748 (published 2019-01-30T18:29Z)

LibVNC before 0.9.12 contains multiple heap out-of-bounds write vulnerabilities in libvncclient/rfbproto.c. The fix for CVE-2018-20019 was incomplete.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-787
cwe_name: Out-of-bounds Write
description: The product writes data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/LibVNC/libvncserver
commit_details: repo_url: https://github.com/LibVNC/libvncserver
author: Christian Beier
author_date: 2018-12-29 14:40:53+01:00
msg: LibVNCClient: ignore server-sent reason strings longer than 1MB

Fixes #273
repository: repo_url: https://github.com/LibVNC/libvncserver
repo_name: LibVNC/libvncserver
description: LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
repo_language: C
owner: LibVNC
file_changes: filename: rfbproto.c
change_type: ModificationType.MODIFY
diff: @@ -412,11 +412,29 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep
 extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
 extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
 
+static void
+ReadReason(rfbClient* client)
+{
+    uint32_t reasonLen;
+    char *reason;
+
+    if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
+    reasonLen = rfbClientSwap32IfLE(reasonLen);
+    if(reasonLen > 1<<20) {
+      rfbClientLog("VNC connection failed, but sent reason length of %u exceeds limit of 1MB",(unsigned int)reasonLen);
+      return;
+    }
+    reason = malloc(reasonLen+1);
+    if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
+    reason[reasonLen]=0;
+    rfbClientLog("VNC connection failed: %s\n",reason);
+    free(reason);
+}
+
 rfbBool
 rfbHandleAuthResult(rfbClient* client)
 {
-    uint32_t authResult=0, reasonLen=0;
-    char *reason=NULL;
+    uint32_t authResult=0;
 
     if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
 
@@ -431,13 +449,7 @@ rfbHandleAuthResult(rfbClient* client)
       if (client->major==3 && client->minor>7)
       {
         /* we have an error following */
-        if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
-        reasonLen = rfbClientSwap32IfLE(reasonLen);
-        reason = malloc((uint64_t)reasonLen+1);
-        if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
-        reason[reasonLen]=0;
-        rfbClientLog("VNC connection failed: %s\n",reason);
-        free(reason);
+        ReadReason(client);
         return FALSE;
       }
       rfbClientLog("VNC authentication failed\n");
@@ -452,21 +464,6 @@ rfbHandleAuthResult(rfbClient* client)
     return FALSE;
 }
 
-static void
-ReadReason(rfbClient* client)
-{
-    uint32_t reasonLen;
-    char *reason;
-
-    /* we have an error following */
-    if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
-    reasonLen = rfbClientSwap32IfLE(reasonLen);
-    reason = malloc((uint64_t)reasonLen+1);
-    if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
-    reason[reasonLen]=0;
-    rfbClientLog("VNC connection failed: %s\n",reason);
-    free(reason);
-}
 
 static rfbBool
 ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)

programming_language: C
repo_url: https://github.com/LibVNC/libvncserver
commit_details: repo_url: https://github.com/LibVNC/libvncserver
author: Christian Beier
author_date: 2018-12-29 14:16:58+01:00
msg: LibVNCClient: ignore server-sent cut text longer than 1MB

This is in line with how LibVNCServer does it
(28afb6c537dc82ba04d5f245b15ca7205c6dbb9c) and fixes part of #273.
repository: repo_url: https://github.com/LibVNC/libvncserver
repo_name: LibVNC/libvncserver
description: LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
repo_language: C
owner: LibVNC
file_changes: filename: rfbproto.c
change_type: ModificationType.MODIFY
diff: @@ -2217,6 +2217,11 @@ HandleRFBServerMessage(rfbClient* client)
 
     msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
 
+    if (msg.sct.length > 1<<20) {
+	    rfbClientErr("Ignoring too big cut text length sent by server: %u B > 1 MB\n", (unsigned int)msg.sct.length);
+	    return FALSE;
+    }  
+
     buffer = malloc((uint64_t)msg.sct.length+1);
 
     if (!ReadFromRFBServer(client, buffer, msg.sct.length)) {

programming_language: C
repo_url: https://github.com/LibVNC/libvncserver
commit_details: repo_url: https://github.com/LibVNC/libvncserver
author: Christian Beier
author_date: 2019-01-06 14:20:37+01:00
msg: LibVNCClient: fail on server-sent desktop name lengths longer than 1MB

re #273
repository: repo_url: https://github.com/LibVNC/libvncserver
repo_name: LibVNC/libvncserver
description: LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
repo_language: C
owner: LibVNC
file_changes: filename: rfbproto.c
change_type: ModificationType.MODIFY
diff: @@ -1224,8 +1224,12 @@ InitialiseRFBConnection(rfbClient* client)
   client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
   client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
 
-  /* To guard against integer wrap-around, si.nameLength is cast to 64 bit */
-  client->desktopName = malloc((uint64_t)client->si.nameLength + 1);
+  if (client->si.nameLength > 1<<20) {
+      rfbClientErr("Too big desktop name length sent by server: %u B > 1 MB\n", (unsigned int)client->si.nameLength);
+      return FALSE;
+  }
+
+  client->desktopName = malloc(client->si.nameLength + 1);
   if (!client->desktopName) {
     rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
             (unsigned long)client->si.nameLength);

programming_language: C
repo_url: https://github.com/LibVNC/libvncserver
commit_details: repo_url: https://github.com/LibVNC/libvncserver
author: Christian Beier
author_date: 2019-01-06 14:22:34+01:00
msg: LibVNCClient: remove now-useless cast

re #273
repository: repo_url: https://github.com/LibVNC/libvncserver
repo_name: LibVNC/libvncserver
description: LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
repo_language: C
owner: LibVNC
file_changes: filename: rfbproto.c
change_type: ModificationType.MODIFY
diff: @@ -2227,7 +2227,7 @@ HandleRFBServerMessage(rfbClient* client)
 	    return FALSE;
     }  
 
-    buffer = malloc((uint64_t)msg.sct.length+1);
+    buffer = malloc(msg.sct.length+1);
 
     if (!ReadFromRFBServer(client, buffer, msg.sct.length)) {
       free(buffer);

programming_language: C