From c3a99fb2c831c2f3da069359a9a8a0c734923669 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 20 Dec 2017 17:56:54 +0100 Subject: [PATCH 14/42] io: monitor encoutput buffer size from websocket GSource RH-Author: Daniel P. Berrange Message-id: <20171220175702.29663-13-berrange@redhat.com> Patchwork-id: 78466 O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 12/20] io: monitor encoutput buffer size from websocket GSource Bugzilla: 1518650 RH-Acked-by: John Snow RH-Acked-by: Jeffrey Cody RH-Acked-by: Miroslav Rezanina The websocket GSource is monitoring the size of the rawoutput buffer to determine if the channel can accepts more writes. The rawoutput buffer, however, is merely a temporary staging buffer before data is copied into the encoutput buffer. Thus its size will always be zero when the GSource runs. This flaw causes the encoutput buffer to grow without bound if the other end of the underlying data channel doesn't read data being sent. This can be seen with VNC if a client is on a slow WAN link and the guest OS is sending many screen updates. A malicious VNC client can act like it is on a slow link by playing a video in the guest and then reading data very slowly, causing QEMU host memory to expand arbitrarily. This issue is assigned CVE-2017-15268, publically reported in https://bugs.launchpad.net/qemu/+bug/1718964 Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange (cherry picked from commit a7b20a8efa28e5f22c26c06cd06c2f12bc863493) Signed-off-by: Miroslav Rezanina --- io/channel-websock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/io/channel-websock.c b/io/channel-websock.c index d1d471f..04bcc05 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -28,7 +28,7 @@ #include -/* Max amount to allow in rawinput/rawoutput buffers */ +/* Max amount to allow in rawinput/encoutput buffers */ #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192 #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24 @@ -1208,7 +1208,7 @@ qio_channel_websock_source_check(GSource *source) if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) { cond |= G_IO_IN; } - if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { + if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { cond |= G_IO_OUT; } -- 1.8.3.1