|
|
9bac43 |
From e3dbec9458073f71290e226ede55734ac4fe7e5d Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
9bac43 |
Date: Mon, 5 Feb 2018 11:10:08 +0100
|
|
|
9bac43 |
Subject: [PATCH 14/20] ui: place a hard cap on VNC server output buffer size
|
|
|
9bac43 |
MIME-Version: 1.0
|
|
|
9bac43 |
Content-Type: text/plain; charset=UTF-8
|
|
|
9bac43 |
Content-Transfer-Encoding: 8bit
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
9bac43 |
Message-id: <20180205111012.6210-14-berrange@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 78890
|
|
|
9bac43 |
O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 13/17] ui: place a hard cap on VNC server output buffer size
|
|
|
9bac43 |
Bugzilla: 1527404
|
|
|
9bac43 |
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
The previous patches fix problems with throttling of forced framebuffer updates
|
|
|
9bac43 |
and audio data capture that would cause the QEMU output buffer size to grow
|
|
|
9bac43 |
without bound. Those fixes are graceful in that once the client catches up with
|
|
|
9bac43 |
reading data from the server, everything continues operating normally.
|
|
|
9bac43 |
|
|
|
9bac43 |
There is some data which the server sends to the client that is impractical to
|
|
|
9bac43 |
throttle. Specifically there are various pseudo framebuffer update encodings to
|
|
|
9bac43 |
inform the client of things like desktop resizes, pointer changes, audio
|
|
|
9bac43 |
playback start/stop, LED state and so on. These generally only involve sending
|
|
|
9bac43 |
a very small amount of data to the client, but a malicious guest might be able
|
|
|
9bac43 |
to do things that trigger these changes at a very high rate. Throttling them is
|
|
|
9bac43 |
not practical as missed or delayed events would cause broken behaviour for the
|
|
|
9bac43 |
client.
|
|
|
9bac43 |
|
|
|
9bac43 |
This patch thus takes a more forceful approach of setting an absolute upper
|
|
|
9bac43 |
bound on the amount of data we permit to be present in the output buffer at
|
|
|
9bac43 |
any time. The previous patch set a threshold for throttling the output buffer
|
|
|
9bac43 |
by allowing an amount of data equivalent to one complete framebuffer update and
|
|
|
9bac43 |
one seconds worth of audio data. On top of this it allowed for one further
|
|
|
9bac43 |
forced framebuffer update to be queued.
|
|
|
9bac43 |
|
|
|
9bac43 |
To be conservative, we thus take that throttling threshold and multiply it by
|
|
|
9bac43 |
5 to form an absolute upper bound. If this bound is hit during vnc_write() we
|
|
|
9bac43 |
forceably disconnect the client, refusing to queue further data. This limit is
|
|
|
9bac43 |
high enough that it should never be hit unless a malicious client is trying to
|
|
|
9bac43 |
exploit the sever, or the network is completely saturated preventing any sending
|
|
|
9bac43 |
of data on the socket.
|
|
|
9bac43 |
|
|
|
9bac43 |
This completes the fix for CVE-2017-15124 started in the previous patches.
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
9bac43 |
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
|
|
|
9bac43 |
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Message-id: 20171218191228.31018-12-berrange@redhat.com
|
|
|
9bac43 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9bac43 |
(cherry picked from commit f887cf165db20f405cb8805c716bd363aaadf815)
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
ui/vnc.c | 29 +++++++++++++++++++++++++++++
|
|
|
9bac43 |
1 file changed, 29 insertions(+)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/ui/vnc.c b/ui/vnc.c
|
|
|
9bac43 |
index 7f2210f..a7aff91 100644
|
|
|
9bac43 |
--- a/ui/vnc.c
|
|
|
9bac43 |
+++ b/ui/vnc.c
|
|
|
9bac43 |
@@ -1521,8 +1521,37 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
|
|
|
9bac43 |
+/*
|
|
|
9bac43 |
+ * Scale factor to apply to vs->throttle_output_offset when checking for
|
|
|
9bac43 |
+ * hard limit. Worst case normal usage could be x2, if we have a complete
|
|
|
9bac43 |
+ * incremental update and complete forced update in the output buffer.
|
|
|
9bac43 |
+ * So x3 should be good enough, but we pick x5 to be conservative and thus
|
|
|
9bac43 |
+ * (hopefully) never trigger incorrectly.
|
|
|
9bac43 |
+ */
|
|
|
9bac43 |
+#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
|
|
|
9bac43 |
+
|
|
|
9bac43 |
void vnc_write(VncState *vs, const void *data, size_t len)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
+ if (vs->disconnecting) {
|
|
|
9bac43 |
+ return;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ /* Protection against malicious client/guest to prevent our output
|
|
|
9bac43 |
+ * buffer growing without bound if client stops reading data. This
|
|
|
9bac43 |
+ * should rarely trigger, because we have earlier throttling code
|
|
|
9bac43 |
+ * which stops issuing framebuffer updates and drops audio data
|
|
|
9bac43 |
+ * if the throttle_output_offset value is exceeded. So we only reach
|
|
|
9bac43 |
+ * this higher level if a huge number of pseudo-encodings get
|
|
|
9bac43 |
+ * triggered while data can't be sent on the socket.
|
|
|
9bac43 |
+ *
|
|
|
9bac43 |
+ * NB throttle_output_offset can be zero during early protocol
|
|
|
9bac43 |
+ * handshake, or from the job thread's VncState clone
|
|
|
9bac43 |
+ */
|
|
|
9bac43 |
+ if (vs->throttle_output_offset != 0 &&
|
|
|
9bac43 |
+ vs->output.offset > (vs->throttle_output_offset *
|
|
|
9bac43 |
+ VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
|
|
|
9bac43 |
+ vnc_disconnect_start(vs);
|
|
|
9bac43 |
+ return;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
buffer_reserve(&vs->output, len);
|
|
|
9bac43 |
|
|
|
9bac43 |
if (vs->ioc != NULL && buffer_empty(&vs->output)) {
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|