From: Denis V. Lunev <[email protected]>
qio_channel_websock_handshake_send() treats every negative return from
qio_channel_write() as fatal and passes err to error_get_pretty().
QIO_CHANNEL_ERR_BLOCK is negative but leaves err NULL, so a socket
which cannot take the response immediately crashes QEMU before the
client has authenticated.
Keep the G_IO_OUT watch armed and retry instead.
Fixes: 2d1d0e70cf3e ("io: add QIOChannelWebsock class")
Fixes: CVE-2026-84788
Cc: [email protected]
Cc: Daniel P. Berrangé <[email protected]>
Cc: Marc-André Lureau <[email protected]>
Reviewed-by: Daniel P. Berrangé <[email protected]>
Reviewed-by: Marc-André Lureau <[email protected]>
Signed-off-by: Denis V. Lunev <[email protected]>
Signed-off-by: Daniel P. Berrangé <[email protected]>
---
io/channel-websock.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 66c91ed2a2..8f27b1f12b 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -562,6 +562,11 @@ static gboolean
qio_channel_websock_handshake_send(QIOChannel *ioc,
wioc->encoutput.offset,
&err);
+ if (ret == QIO_CHANNEL_ERR_BLOCK) {
+ /* Socket buffer is full, the G_IO_OUT watch stays armed */
+ return TRUE;
+ }
+
if (ret < 0) {
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
--
2.55.0