From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Daniel P. Berrange" <berrange@redhat.com>,
Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PULL 12/14] ui: place a hard cap on VNC server output buffer size
Date: Fri, 12 Jan 2018 13:58:52 +0100 [thread overview]
Message-ID: <20180112125854.18261-13-kraxel@redhat.com> (raw)
In-Reply-To: <20180112125854.18261-1-kraxel@redhat.com>
From: "Daniel P. Berrange" <berrange@redhat.com>
The previous patches fix problems with throttling of forced framebuffer updates
and audio data capture that would cause the QEMU output buffer size to grow
without bound. Those fixes are graceful in that once the client catches up with
reading data from the server, everything continues operating normally.
There is some data which the server sends to the client that is impractical to
throttle. Specifically there are various pseudo framebuffer update encodings to
inform the client of things like desktop resizes, pointer changes, audio
playback start/stop, LED state and so on. These generally only involve sending
a very small amount of data to the client, but a malicious guest might be able
to do things that trigger these changes at a very high rate. Throttling them is
not practical as missed or delayed events would cause broken behaviour for the
client.
This patch thus takes a more forceful approach of setting an absolute upper
bound on the amount of data we permit to be present in the output buffer at
any time. The previous patch set a threshold for throttling the output buffer
by allowing an amount of data equivalent to one complete framebuffer update and
one seconds worth of audio data. On top of this it allowed for one further
forced framebuffer update to be queued.
To be conservative, we thus take that throttling threshold and multiply it by
5 to form an absolute upper bound. If this bound is hit during vnc_write() we
forceably disconnect the client, refusing to queue further data. This limit is
high enough that it should never be hit unless a malicious client is trying to
exploit the sever, or the network is completely saturated preventing any sending
of data on the socket.
This completes the fix for CVE-2017-15124 started in the previous patches.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20171218191228.31018-12-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/ui/vnc.c b/ui/vnc.c
index 4805ac41d0..e53e84587a 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1521,8 +1521,37 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
}
+/*
+ * Scale factor to apply to vs->throttle_output_offset when checking for
+ * hard limit. Worst case normal usage could be x2, if we have a complete
+ * incremental update and complete forced update in the output buffer.
+ * So x3 should be good enough, but we pick x5 to be conservative and thus
+ * (hopefully) never trigger incorrectly.
+ */
+#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
+
void vnc_write(VncState *vs, const void *data, size_t len)
{
+ if (vs->disconnecting) {
+ return;
+ }
+ /* Protection against malicious client/guest to prevent our output
+ * buffer growing without bound if client stops reading data. This
+ * should rarely trigger, because we have earlier throttling code
+ * which stops issuing framebuffer updates and drops audio data
+ * if the throttle_output_offset value is exceeded. So we only reach
+ * this higher level if a huge number of pseudo-encodings get
+ * triggered while data can't be sent on the socket.
+ *
+ * NB throttle_output_offset can be zero during early protocol
+ * handshake, or from the job thread's VncState clone
+ */
+ if (vs->throttle_output_offset != 0 &&
+ vs->output.offset > (vs->throttle_output_offset *
+ VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
+ vnc_disconnect_start(vs);
+ return;
+ }
buffer_reserve(&vs->output, len);
if (vs->ioc != NULL && buffer_empty(&vs->output)) {
--
2.9.3
next prev parent reply other threads:[~2018-01-12 12:59 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-12 12:58 [Qemu-devel] [PULL 00/14] Vnc 20180112 patches Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 01/14] vnc: fix debug spelling Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 02/14] ui: remove 'sync' parameter from vnc_update_client Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 03/14] ui: remove unreachable code in vnc_update_client Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 04/14] ui: remove redundant indentation in vnc_client_update Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 05/14] ui: avoid pointless VNC updates if framebuffer isn't dirty Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 06/14] ui: track how much decoded data we consumed when doing SASL encoding Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 07/14] ui: introduce enum to track VNC client framebuffer update request state Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 08/14] ui: correctly reset framebuffer update state after processing dirty regions Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 09/14] ui: refactor code for determining if an update should be sent to the client Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 10/14] ui: fix VNC client throttling when audio capture is active Gerd Hoffmann
2018-01-18 13:29 ` Peter Maydell
2018-01-18 13:36 ` Daniel P. Berrange
2018-01-18 13:54 ` Paolo Bonzini
2018-01-18 14:12 ` Daniel P. Berrange
2018-01-18 14:46 ` Paolo Bonzini
2018-01-18 14:50 ` Peter Maydell
2018-01-18 15:33 ` Paolo Bonzini
2018-01-18 16:06 ` Thomas Huth
2018-01-18 16:13 ` Paolo Bonzini
2018-01-25 9:08 ` Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 11/14] ui: fix VNC client throttling when forced update is requested Gerd Hoffmann
2018-01-12 12:58 ` Gerd Hoffmann [this message]
2018-01-12 16:40 ` [Qemu-devel] [PULL 12/14] ui: place a hard cap on VNC server output buffer size Peter Maydell
2018-01-12 16:50 ` Daniel P. Berrange
2018-01-12 12:58 ` [Qemu-devel] [PULL 13/14] ui: add trace events related to VNC client throttling Gerd Hoffmann
2018-01-12 12:58 ` [Qemu-devel] [PULL 14/14] ui: mix misleading comments & return types of VNC I/O helper methods Gerd Hoffmann
2018-01-12 16:41 ` [Qemu-devel] [PULL 00/14] Vnc 20180112 patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180112125854.18261-13-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).