Skip to content

libvncserver: Segmentation Fault on Client Disconnect with Secure WebSockets #665

@guti101

Description

@guti101

If you'd like to put out an incentive for fixing this bug, you can do so at https://issuehunt.io/r/LibVNC/libvncserver

Describe the bug

We are experiencing a segmentation fault in libvncserver when a client disconnects while using secure web sockets (wss). The issue appears intermittently and is reproducible with both OpenSSL and GnuTLS.

The core problem seems to be related to the premature or incorrect freeing of the SSL context associated with a client connection after the client disconnects or becomes inactive.

Specifically:

A VNC client connects, and an SSL context is created and associated with that connection.
The client disconnects or becomes inactive.
The code attempts to free the SSL context associated with the client connection immediately or prematurely.
A subsequent operation (specifically, attempting to send a screen update) then tries to use the freed SSL context for SSL_write. This operation leads to an access violation (segmentation fault) because it's attempting to access freed memory.
This is happening intermittently, suggesting a potential race condition or timing issue related to the handling of client disconnections and SSL context cleanup.

To Reproduce

  1. Configure libvncserver to use secure web sockets.
  2. Using a screen with many changes makes the segfault more likely to happen
  3. Connect a VNC client to the server over wss.
  4. Disconnect the client.
  5. Repeat step 3+4 until the segmentation fault happens.

Expected Behavior
The LibVNCServer should not crash or exhibit a segmentation fault following a client disconnect.

Logs/Backtraces

gnutls:

Invalid read of size 8
   at 0x4F91332: gnutls_x509_trust_list_deinit (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x4F01CCA: gnutls_certificate_free_credentials (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x487B41F: rfbssl_destroy (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4864498: rfbCloseClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485FDE0: rfbSendUpdateBuf (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4886EBB: SendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4886E50: rfbSendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485EF47: rfbSendFramebufferUpdate (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4853C5D: clientOutput (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E1EA6: start_thread (pthread_create.c:477)
   by 0x4BE0ADE: clone (clone.S:95)
 Address 0x8482ce8 is 8 bytes inside a block of size 88 free'd
   at 0x48399AB: free (vg_replace_malloc.c:538)
   by 0x4F01CCA: gnutls_certificate_free_credentials (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x487B41F: rfbssl_destroy (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4864498: rfbCloseClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485AC56: rfbProcessClientNormalMessage (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4856D0A: rfbProcessClientMessage (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485407C: clientInput (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E1EA6: start_thread (pthread_create.c:477)
   by 0x4BE0ADE: clone (clone.S:95)
 Block was alloc'd at
   at 0x483AB65: calloc (vg_replace_malloc.c:760)
   by 0x4F911E4: gnutls_x509_trust_list_init (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x4F01D79: gnutls_certificate_allocate_credentials (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x487AD8C: rfbssl_init_global (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x487AF16: rfbssl_init (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4892A77: webSocketsCheck (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4856601: rfbNewTCPOrUDPClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48567E3: rfbNewClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48544BF: listenerRun (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E1EA6: start_thread (pthread_create.c:477)
   by 0x4BE0ADE: clone (clone.S:95)

Invalid read of size 8
   at 0x4F9139A: gnutls_x509_trust_list_deinit (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x4F01CCA: gnutls_certificate_free_credentials (in /usr/lib/x86_64-linux-gnu/libgnutls.so.30.29.1)
   by 0x487B41F: rfbssl_destroy (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4864498: rfbCloseClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485FDE0: rfbSendUpdateBuf (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4886EBB: SendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4886E50: rfbSendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485EF47: rfbSendFramebufferUpdate (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4853C5D: clientOutput (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E1EA6: start_thread (pthread_create.c:477)
   by 0x4BE0ADE: clone (clone.S:95)
 Address 0x0 is not stack'd, malloc'd or (recently) free'd

openssl:

Invalid read of size 8
   at 0x4DBD007: ??? (in /usr/lib/x86_64-linux-gnu/libssl.so.1.1)
   by 0x4DCFA02: SSL_write (in /usr/lib/x86_64-linux-gnu/libssl.so.1.1)
   by 0x487BFDA: rfbssl_write (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4866089: rfbWriteExact (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4861088: rfbSendUpdateBuf (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x488ADB5: SendSubrect (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x488AD51: SendRectSimple (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4889E95: SendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4889BF6: rfbSendRectEncodingTight (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48601D5: rfbSendFramebufferUpdate (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4854D5D: clientOutput (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E4EA6: start_thread (pthread_create.c:477)
 Address 0x7c6ab38 is 168 bytes inside a block of size 6,280 free'd
   at 0x48399AB: free (vg_replace_malloc.c:538)
   by 0x487C122: rfbssl_destroy (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x486575C: rfbCloseClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485BD56: rfbProcessClientNormalMessage (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4857E0A: rfbProcessClientMessage (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x485517C: clientInput (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E4EA6: start_thread (pthread_create.c:477)
   by 0x4BE3ADE: clone (clone.S:95)
 Block was alloc'd at
   at 0x483877F: malloc (vg_replace_malloc.c:307) 		
   by 0x4FBF349: CRYPTO_zalloc (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
   by 0x4DD3DE4: SSL_new (in /usr/lib/x86_64-linux-gnu/libssl.so.1.1)
   by 0x487BE80: rfbssl_init (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4895CBC: webSocketsCheck (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x4857701: rfbNewTCPOrUDPClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48578E3: rfbNewClient (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48555BF: listenerRun (in /usr/local/lib/libvncserver.so.0.9.15)
   by 0x48E4EA6: start_thread (pthread_create.c:477)
   by 0x4BE3ADE: clone (clone.S:95)

Your environment (please complete the following information):

  • OS and version: Debian 11.11
  • Compiler and version: gcc 10.2.1
  • OpenSSL: 1.1.1w
  • libgnutls: 3.7.1-5+deb11u7
  • libvncserver 0.9.15 and current master

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions