Commit 7a72a4652a for qemu.org

commit 7a72a4652a7955db579d2b9244a09edbf7b0529b
Author: Denis V. Lunev <den@openvz.org>
Date:   Mon Aug 31 12:01:50 2026 +0200

    io/channel-websock: do not lose QIO_CHANNEL_ERR_BLOCK while reading

    qio_channel_websock_handshake_read() folds every negative return from
    qio_channel_read() into -1. QIO_CHANNEL_ERR_BLOCK leaves errp unset, so
    qio_channel_websock_handshake_io() then hands a NULL Error to
    error_get_pretty() and QEMU dies.

    The master channel is non-blocking and, for a wss:// client, is a TLS
    channel. A G_IO_IN wakeup carrying only part of a TLS record makes
    gnutls report EAGAIN, which is all it takes to reach this before the
    client has authenticated.

    ERR_BLOCK here means the headers are not complete yet, which is what a
    0 return already tells the caller. Report it that way and keep waiting.
    The watch is level triggered, so an incomplete record sitting in the
    socket spins the main loop until the rest of it arrives. That is
    bounded by the round trip and is what every reader layered over TLS
    already does.

    Fixes: 2d1d0e70cf3e ("io: add QIOChannelWebsock class")
    Fixes: CVE-2026-84788
    Cc: qemu-stable@nongnu.org
    Cc: Daniel P. Berrangé <berrange@redhat.com>
    Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
    Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
    Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
    Signed-off-by: Denis V. Lunev <den@openvz.org>
    Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

diff --git a/io/channel-websock.c b/io/channel-websock.c
index 8f27b1f12b..461abcae48 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -492,6 +492,9 @@ static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
     buffer_reserve(&ioc->encinput, want);
     ret = qio_channel_read(ioc->master,
                            (char *)buffer_end(&ioc->encinput), want, errp);
+    if (ret == QIO_CHANNEL_ERR_BLOCK) {
+        return 0;
+    }
     if (ret < 0) {
         return -1;
     }