On Tue, Sep 16, 2025 at 09:41:53PM +0800, zoudongjie via wrote:
> When qemu is performing a TLS handshake for VNC, it will monitor vs->sioc
> in the qio_channel_tls_handshake_task. If the number of concurrent VNC
> connections exceeds the maximum number allowed by qemu, vnc_connect will
> traverse all connection requests in share mode VNC_SHARE_MODE_CONNECTING
> and disconnect the first one.
> 
> If the disconnected request has not yet entered qio_channel_tls_handshake_io,
> it will cause the data pointer allocated in qio_channel_tls_handshake_task
> to leak directly, leading to an indirect leak of the task and its associated
> pointers.

The qio_channel_tls_close method will cancel the pending handshake by
calling g_clear_handle_id. The problem is that when we do that, we fail
to release the QIOTask object because that is only freed when
qio_channel_tls_handshake is called on completion triggering use of
qio_task_complete.

The problem here is that we broadly mis-used the APIs for sources...

> @@ -201,13 +219,23 @@ static void 
> qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
>          }
>  
>          trace_qio_channel_tls_handshake_pending(ioc, status);
> -        ioc->hs_ioc_tag =
> -            qio_channel_add_watch_full(ioc->master,
> -                                       condition,
> -                                       qio_channel_tls_handshake_io,
> -                                       data,
> -                                       NULL,
> -                                       context);

...instead of NULL we should have passed a method that can free
the 'data' object there, as well as the QIOTask that 'data'
contains a reference to.

The qio_task_complete method should not then free the task.



With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Reply via email to