The websock code will create a GSource for tracking completion of the
handshake process, passing a QIOTask which is freed by the callback
when it completes, which means when a source is cancelled, nothing is
free'ing the task.
Switch to provide a data free callback to the GSource, which ensures
the QIOTask is always freed even when the main event callback never
fires.
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3114
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
io/channel-websock.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/io/channel-websock.c b/io/channel-websock.c
index b4f96a0af4..6d92be4fa1 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -545,7 +545,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
- qio_task_free(task);
wioc->hs_io_tag = 0;
return FALSE;
}
@@ -562,7 +561,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
trace_qio_channel_websock_handshake_complete(ioc);
qio_task_complete(task);
}
- qio_task_free(task);
wioc->hs_io_tag = 0;
return FALSE;
}
@@ -590,7 +588,6 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
- qio_task_free(task);
wioc->hs_io_tag = 0;
return FALSE;
}
@@ -918,7 +915,7 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
G_IO_IN,
qio_channel_websock_handshake_io,
task,
- NULL);
+ (GDestroyNotify)qio_task_free);
}
--
2.52.0
On Wed, Jan 7, 2026 at 7:36 PM Daniel P. Berrangé <berrange@redhat.com> wrote: > > The websock code will create a GSource for tracking completion of the > handshake process, passing a QIOTask which is freed by the callback > when it completes, which means when a source is cancelled, nothing is > free'ing the task. > > Switch to provide a data free callback to the GSource, which ensures > the QIOTask is always freed even when the main event callback never > fires. > > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3114 > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> > --- > io/channel-websock.c | 5 +---- > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/io/channel-websock.c b/io/channel-websock.c > index b4f96a0af4..6d92be4fa1 100644 > --- a/io/channel-websock.c > +++ b/io/channel-websock.c > @@ -545,7 +545,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc, > trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err)); > qio_task_set_error(task, err); > qio_task_complete(task); > - qio_task_free(task); > wioc->hs_io_tag = 0; > return FALSE; > } > @@ -562,7 +561,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc, > trace_qio_channel_websock_handshake_complete(ioc); > qio_task_complete(task); > } > - qio_task_free(task); > wioc->hs_io_tag = 0; > return FALSE; > } > @@ -590,7 +588,6 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc, > trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err)); > qio_task_set_error(task, err); > qio_task_complete(task); > - qio_task_free(task); > wioc->hs_io_tag = 0; > return FALSE; > } > @@ -918,7 +915,7 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc, > G_IO_IN, > qio_channel_websock_handshake_io, > task, > - NULL); > + (GDestroyNotify)qio_task_free); > } > > > -- > 2.52.0 > > -- Marc-André Lureau
© 2016 - 2026 Red Hat, Inc.