CVE-2016-10207 (published 2017-02-28T18:59Z)

The Xvnc server in TigerVNC allows remote attackers to cause a denial of service (invalid memory access and crash) by terminating a TLS handshake early.

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

Weakness information:
cwe_id: CWE-119
cwe_name: Improper Restriction of Operations within the Bounds of a Memory Buffer
description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
extended_description: 
            Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced. This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data.
         
         

Fix information:
repo_url: https://github.com/TigerVNC/tigervnc
commit_details: repo_url: https://github.com/TigerVNC/tigervnc
author: Pierre Ossman
author_date: 2016-08-23 17:02:58+02:00
msg: Proper global init/deinit of GnuTLS

These are reference counted so it is important to retain symmetry
between the calls. Failure to do so will result in bad memory access
and crashes.
repository: repo_url: https://github.com/TigerVNC/tigervnc
repo_name: TigerVNC/tigervnc
description: High performance, multi-platform VNC client and server
repo_language: C++
owner: TigerVNC
file_changes: filename: CSecurityTLS.cxx
change_type: ModificationType.MODIFY
diff: @@ -67,21 +67,14 @@ StringParameter CSecurityTLS::X509CRL("X509CRL", "X509 CRL file", "", ConfViewer
 
 static LogWriter vlog("TLS");
 
-void CSecurityTLS::initGlobal()
-{
-  static bool globalInitDone = false;
-
-  if (!globalInitDone) {
-    gnutls_global_init();
-    globalInitDone = true;
-  }
-}
-
 CSecurityTLS::CSecurityTLS(bool _anon) : session(0), anon_cred(0),
 						 anon(_anon), fis(0), fos(0)
 {
   cafile = X509CA.getData();
   crlfile = X509CRL.getData();
+
+  if (gnutls_global_init() != GNUTLS_E_SUCCESS)
+    throw AuthFailureException("gnutls_global_init failed");
 }
 
 void CSecurityTLS::setDefaults()
@@ -125,8 +118,6 @@ void CSecurityTLS::shutdown(bool needbye)
   if (session) {
     gnutls_deinit(session);
     session = 0;
-
-    gnutls_global_deinit();
   }
 }
 
@@ -142,6 +133,8 @@ CSecurityTLS::~CSecurityTLS()
 
   delete[] cafile;
   delete[] crlfile;
+
+  gnutls_global_deinit();
 }
 
 bool CSecurityTLS::processMsg(CConnection* cc)
@@ -150,8 +143,6 @@ bool CSecurityTLS::processMsg(CConnection* cc)
   rdr::OutStream* os = cc->getOutStream();
   client = cc;
 
-  initGlobal();
-
   if (!session) {
     if (!is->checkNoWait(1))
       return false;

programming_language: C++
filename: CSecurityTLS.h
change_type: ModificationType.MODIFY
diff: @@ -62,8 +62,6 @@ namespace rfb {
     CConnection *client;
 
   private:
-    static void initGlobal();
-
     gnutls_session_t session;
     gnutls_anon_client_credentials_t anon_cred;
     gnutls_certificate_credentials_t cert_cred;

programming_language: C++
filename: SSecurityTLS.cxx
change_type: ModificationType.MODIFY
diff: @@ -48,23 +48,15 @@ StringParameter SSecurityTLS::X509_KeyFile
 
 static LogWriter vlog("TLS");
 
-void SSecurityTLS::initGlobal()
-{
-  static bool globalInitDone = false;
-
-  if (!globalInitDone) {
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-      throw AuthFailureException("gnutls_global_init failed");
-    globalInitDone = true;
-  }
-}
-
 SSecurityTLS::SSecurityTLS(bool _anon) : session(0), dh_params(0),
 						 anon_cred(0), cert_cred(0),
 						 anon(_anon), fis(0), fos(0)
 {
   certfile = X509_CertFile.getData();
   keyfile = X509_KeyFile.getData();
+
+  if (gnutls_global_init() != GNUTLS_E_SUCCESS)
+    throw AuthFailureException("gnutls_global_init failed");
 }
 
 void SSecurityTLS::shutdown()
@@ -94,8 +86,6 @@ void SSecurityTLS::shutdown()
   if (session) {
     gnutls_deinit(session);
     session = 0;
-
-    gnutls_global_deinit();
   }
 }
 
@@ -111,6 +101,8 @@ SSecurityTLS::~SSecurityTLS()
 
   delete[] keyfile;
   delete[] certfile;
+
+  gnutls_global_deinit();
 }
 
 bool SSecurityTLS::processMsg(SConnection *sc)
@@ -121,8 +113,6 @@ bool SSecurityTLS::processMsg(SConnection *sc)
   vlog.debug("Process security message (session %p)", session);
 
   if (!session) {
-    initGlobal();
-
     if (gnutls_init(&session, GNUTLS_SERVER) != GNUTLS_E_SUCCESS)
       throw AuthFailureException("gnutls_init failed");
 

programming_language: C++
filename: SSecurityTLS.h
change_type: ModificationType.MODIFY
diff: @@ -54,8 +54,6 @@ namespace rfb {
     void setParams(gnutls_session_t session);
 
   private:
-    static void initGlobal();
-
     gnutls_session_t session;
     gnutls_dh_params_t dh_params;
     gnutls_anon_server_credentials_t anon_cred;

programming_language: C++