mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 14:04:39 +08:00
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:2d1d0e70cf("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> (cherry picked from commit7a72a4652a) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
1 parent
db6c3cda38
commit
f35b86fbc1
1 file changed
+3
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user