]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/CVE-2015-1779-limit-size-of-HTTP-headers-from-websockets-clients.patch
Fix CVE-2016-2841, CVE-2016-2857, CVE-2016-2858
[pve-qemu-kvm.git] / debian / patches / CVE-2015-1779-limit-size-of-HTTP-headers-from-websockets-clients.patch
1 From 2cdb5e142fb93e875fa53c52864ef5eb8d5d8b41 Mon Sep 17 00:00:00 2001
2 From: "Daniel P. Berrange" <berrange@redhat.com>
3 Date: Mon, 23 Mar 2015 22:58:22 +0000
4 Subject: [PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets
5 clients
6
7 The VNC server websockets decoder will read and buffer data from
8 websockets clients until it sees the end of the HTTP headers,
9 as indicated by \r\n\r\n. In theory this allows a malicious to
10 trick QEMU into consuming an arbitrary amount of RAM. In practice,
11 because QEMU runs g_strstr_len() across the buffered header data,
12 it will spend increasingly long burning CPU time searching for
13 the substring match and less & less time reading data. So while
14 this does cause arbitrary memory growth, the bigger problem is
15 that QEMU will be burning 100% of available CPU time.
16
17 A novnc websockets client typically sends headers of around
18 512 bytes in length. As such it is reasonable to place a 4096
19 byte limit on the amount of data buffered while searching for
20 the end of HTTP headers.
21
22 Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
23 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
24 ---
25 ui/vnc-ws.c | 10 ++++++++--
26 1 file changed, 8 insertions(+), 2 deletions(-)
27
28 diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
29 index 0b7de4e..62eb97f 100644
30 --- a/ui/vnc-ws.c
31 +++ b/ui/vnc-ws.c
32 @@ -81,8 +81,11 @@ void vncws_handshake_read(void *opaque)
33 VncState *vs = opaque;
34 uint8_t *handshake_end;
35 long ret;
36 - buffer_reserve(&vs->ws_input, 4096);
37 - ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096);
38 + /* Typical HTTP headers from novnc are 512 bytes, so limiting
39 + * total header size to 4096 is easily enough. */
40 + size_t want = 4096 - vs->ws_input.offset;
41 + buffer_reserve(&vs->ws_input, want);
42 + ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want);
43
44 if (!ret) {
45 if (vs->csock == -1) {
46 @@ -99,6 +102,9 @@ void vncws_handshake_read(void *opaque)
47 vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset);
48 buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
49 strlen(WS_HANDSHAKE_END));
50 + } else if (vs->ws_input.offset >= 4096) {
51 + VNC_DEBUG("End of headers not found in first 4096 bytes\n");
52 + vnc_client_error(vs);
53 }
54 }
55
56 --
57 2.1.4
58