cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-CVE-2015-1779-limit-size-of-HTTP-headers-from-websoc.patch

605027
From 7721e2e58f7cd2fcf835800622b8a7e1cdeb4557 Mon Sep 17 00:00:00 2001
605027
From: Gerd Hoffmann <kraxel@redhat.com>
605027
Date: Tue, 22 Sep 2015 17:44:54 +0200
605027
Subject: [PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets
605027
 clients
605027
605027
Message-id: <1442943894-7638-3-git-send-email-kraxel@redhat.com>
605027
Patchwork-id: 67885
605027
O-Subject: [RHEL-7.1.z qemu-kvm PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets clients
605027
Bugzilla: 1205050
605027
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
605027
RH-Acked-by: Thomas Huth <thuth@redhat.com>
605027
RH-Acked-by: Petr Matousek <pmatouse@redhat.com>
605027
605027
From: "Daniel P. Berrange" <berrange@redhat.com>
605027
605027
The VNC server websockets decoder will read and buffer data from
605027
websockets clients until it sees the end of the HTTP headers,
605027
as indicated by \r\n\r\n. In theory this allows a malicious to
605027
trick QEMU into consuming an arbitrary amount of RAM. In practice,
605027
because QEMU runs g_strstr_len() across the buffered header data,
605027
it will spend increasingly long burning CPU time searching for
605027
the substring match and less & less time reading data. So while
605027
this does cause arbitrary memory growth, the bigger problem is
605027
that QEMU will be burning 100% of available CPU time.
605027
605027
A novnc websockets client typically sends headers of around
605027
512 bytes in length. As such it is reasonable to place a 4096
605027
byte limit on the amount of data buffered while searching for
605027
the end of HTTP headers.
605027
605027
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
605027
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
605027
(cherry picked from commit 2cdb5e142fb93e875fa53c52864ef5eb8d5d8b41)
605027
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
605027
---
605027
 ui/vnc-ws.c | 10 ++++++++--
605027
 1 file changed, 8 insertions(+), 2 deletions(-)
605027
605027
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
605027
index a7d457c..7133be9 100644
605027
--- a/ui/vnc-ws.c
605027
+++ b/ui/vnc-ws.c
605027
@@ -88,8 +88,11 @@ void vncws_handshake_read(void *opaque)
605027
     VncState *vs = opaque;
605027
     uint8_t *handshake_end;
605027
     long ret;
605027
-    buffer_reserve(&vs->ws_input, 4096);
605027
-    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096);
605027
+    /* Typical HTTP headers from novnc are 512 bytes, so limiting
605027
+     * total header size to 4096 is easily enough. */
605027
+    size_t want = 4096 - vs->ws_input.offset;
605027
+    buffer_reserve(&vs->ws_input, want);
605027
+    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want);
605027
 
605027
     if (!ret) {
605027
         if (vs->csock == -1) {
605027
@@ -106,6 +109,9 @@ void vncws_handshake_read(void *opaque)
605027
         vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset);
605027
         buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
605027
                 strlen(WS_HANDSHAKE_END));
605027
+    } else if (vs->ws_input.offset >= 4096) {
605027
+        VNC_DEBUG("End of headers not found in first 4096 bytes\n");
605027
+        vnc_client_error(vs);
605027
     }
605027
 }
605027
 
605027
-- 
605027
1.8.3.1
605027