diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2015-03-23 22:58:21 +0000 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2015-04-01 17:11:34 +0200 |
commit | a2bebfd6e09d285aa793cae3fb0fc3a39a9fee6e (patch) | |
tree | 50dd263e322551021e69347f95dfb0aef5a0a2ac /ui/vnc-ws.h | |
parent | b8a86c4ac4d04c106ba38fbd707041cba334a155 (diff) |
CVE-2015-1779: incrementally decode websocket frames
The logic for decoding websocket frames wants to fully
decode the frame header and payload, before allowing the
VNC server to see any of the payload data. There is no
size limit on websocket payloads, so this allows a
malicious network client to consume 2^64 bytes in memory
in QEMU. It can trigger this denial of service before
the VNC server even performs any authentication.
The fix is to decode the header, and then incrementally
decode the payload data as it is needed. With this fix
the websocket decoder will allow at most 4k of data to
be buffered before decoding and processing payload.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
[ kraxel: fix frequent spurious disconnects, suggested by Peter Maydell ]
@@ -361,7 +361,7 @@ int vncws_decode_frame_payload(Buffer *input,
- *payload_size = input->offset;
+ *payload_size = *payload_remain;
[ kraxel: fix 32bit build ]
@@ -306,7 +306,7 @@ struct VncState
- uint64_t ws_payload_remain;
+ size_t ws_payload_remain;
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'ui/vnc-ws.h')
-rw-r--r-- | ui/vnc-ws.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h index ef229b7c0c..14d4230eff 100644 --- a/ui/vnc-ws.h +++ b/ui/vnc-ws.h @@ -83,7 +83,12 @@ long vnc_client_read_ws(VncState *vs); void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size); void vncws_encode_frame(Buffer *output, const void *payload, const size_t payload_size); -int vncws_decode_frame(Buffer *input, uint8_t **payload, - size_t *payload_size, size_t *frame_size); +int vncws_decode_frame_header(Buffer *input, + size_t *header_size, + size_t *payload_remain, + WsMask *payload_mask); +int vncws_decode_frame_payload(Buffer *input, + size_t *payload_remain, WsMask *payload_mask, + uint8_t **payload, size_t *payload_size); #endif /* __QEMU_UI_VNC_WS_H */ |