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 :|