aboutsummaryrefslogtreecommitdiff
path: root/io/channel-websock.c
AgeCommit message (Collapse)AuthorFilesLines
2019-06-12Include qemu/module.h where needed, drop it from qemu-common.hMarkus Armbruster1-0/+1
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20190523143508.25387-4-armbru@redhat.com> [Rebased with conflicts resolved automatically, except for hw/usb/dev-hub.c hw/misc/exynos4210_rng.c hw/misc/bcm2835_rng.c hw/misc/aspeed_scu.c hw/display/virtio-vga.c hw/arm/stm32f205_soc.c; ui/cocoa.m fixed up]
2019-03-20io: fix handling of EOF / error conditions in websock GSourceDaniel P. Berrangé1-1/+7
We were never reporting the G_IO_HUP event when an end of file was hit on the websocket channel. We also didn't report G_IO_ERR when we hit a fatal error processing the websocket protocol. The latter in particular meant that the chardev code would not notice when an eof/error was encountered on the websocket channel, unless the guest OS happened to trigger a write operation. This meant that once the first client had quit, the chardev would never listen to accept a new client. Fixes launchpad bug 1816819 Acked-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-11-01websock: fix handshake leakMarc-André Lureau1-0/+1
Missed in f69a8bde293. Thanks Valgrind: ==955== 217 bytes in 1 blocks are definitely lost in loss record 275 of 321 ==955== at 0x483A965: realloc (vg_replace_malloc.c:785) ==955== by 0x50B6839: __vasprintf_chk (in /usr/lib64/libc-2.28.so) ==955== by 0x49AA05C: g_vasprintf (in /usr/lib64/libglib-2.0.so.0.5800.1) ==955== by 0x4983440: g_strdup_vprintf (in /usr/lib64/libglib-2.0.so.0.5800.1) ==955== by 0x126048: qio_channel_websock_handshake_send_res (channel-websock.c:162) ==955== by 0x1266E6: qio_channel_websock_handshake_send_res_ok (channel-websock.c:362) ==955== by 0x126D3E: qio_channel_websock_handshake_process (channel-websock.c:468) ==955== by 0x126EF2: qio_channel_websock_handshake_read (channel-websock.c:511) ==955== by 0x12715B: qio_channel_websock_handshake_io (channel-websock.c:571) ==955== by 0x125027: qio_channel_fd_source_dispatch (channel-watch.c:84) ==955== by 0x496326C: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5800.1) ==955== by 0x169EC3: glib_pollfds_poll (main-loop.c:215) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-03-27error: Remove NULL checks on error_propagate() callsLaurent Vivier1-3/+1
Re-run Coccinelle patch scripts/coccinelle/error_propagate_null.cocci Signed-off-by: Laurent Vivier <lvivier@redhat.com> Message-Id: <20180323143202.28879-4-lvivier@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-02-15io/channel-websock: handle continuous reads without any dataEdgar Kaziakhmedov1-2/+5
According to the current implementation of websocket protocol in QEMU, qio_channel_websock_handshake_io tries to read handshake from the channel to start communication over socket. But this approach doesn't cover scenario when socket was closed while handshaking. Therefore, if G_IO_IN is caught and qio_channel_read returns zero, error has to be set and connection has to be done. Such behaviour causes 100% CPU load in main QEMU loop, because main loop poll continues to receive and handle G_IO_IN events from websocket. Step to reproduce 100% CPU load: 1) start qemu with the simplest configuration $ qemu -vnc [::1]:1,websocket=7500 2) open any vnc listener (which doesn't follow websocket protocol) $ vncviewer :7500 3) kill listener 4) qemu main thread eats 100% CPU Signed-off-by: Edgar Kaziakhmedov <edgar.kaziakhmedov@virtuozzo.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2018-02-09Clean up includesMarkus Armbruster1-3/+0
Clean up includes so that osdep.h is included first and headers which it implies are not included manually. This commit was created with scripts/clean-includes, with the change to target/s390x/gen-features.c manually reverted, and blank lines around deletions collapsed. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180201111846.21846-3-armbru@redhat.com>
2017-10-17Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-fetch' into ↵Peter Maydell1-3/+4
staging trivial patches for 2017-10-16 # gpg: Signature made Mon 16 Oct 2017 21:32:05 BST # gpg: using RSA key 0x701B4F6B1A693E59 # gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>" # gpg: aka "Michael Tokarev <mjt@corpit.ru>" # gpg: aka "Michael Tokarev <mjt@debian.org>" # Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D 4324 457C E0A0 8044 65C5 # Subkey fingerprint: 7B73 BAD6 8BE7 A2C2 8931 4B22 701B 4F6B 1A69 3E59 * remotes/mjt/tags/trivial-patches-fetch: Add myself as maintainer for TPM code filter-mirror: segfault when specifying non existent device MAINTAINERS: Track default-configs/pci.mak MAINTAINERS: Fix Sun4v file MAINTAINERS: Clean up SCSI device section include/hw/or-irq.h: Drop unused in_irqs field io: Add missing GCC_FMT_ATTR (fix -Werror=suggest-attribute=format) os-posix: Drop misleading comment linux-user: Add some random ioctls futex: add missing header guards ui/gtk: Fix deprecation of vte_terminal_copy_clipboard gitignore: ignore check-qlit test linux-user: remove duplicate break in syscall qemu-doc.texi: remove trailing whitespace Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-10-16io: Add missing GCC_FMT_ATTR (fix -Werror=suggest-attribute=format)Stefan Weil1-3/+4
This fixes a compiler warning: /qemu/io/channel-websock.c:163:5: error: function might be possible candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] Signed-off-by: Stefan Weil <sw@weilnetz.de> Acked-by: Daniel P. Berrange <berrange@redhat.com> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2017-10-16io: fix mem leak in websock error pathDaniel P. Berrange1-1/+2
Coverity pointed out the 'date' is not free()d in the error path Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: add trace points for websocket HTTP protocol headersDaniel P. Berrange1-0/+4
Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: cope with websock 'Connection' header having multiple valuesDaniel P. Berrange1-1/+13
The noVNC server sends a header "Connection: keep-alive, Upgrade" which fails our simple equality test. Split the header on ',', trim whitespace and then check for 'upgrade' token. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: get rid of bounce buffering in websock write pathDaniel P. Berrange1-36/+28
Currently most outbound I/O on the websock channel gets copied into the rawoutput buffer, and then immediately copied again into the encoutput buffer, with a header prepended. Now that qio_channel_websock_encode accepts a struct iovec, we can trivially remove this bounce buffering and write directly to encoutput. In doing so, we also now correctly validate the encoutput size against the QIO_CHANNEL_WEBSOCK_MAX_BUFFER limit. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: pass a struct iovec into qio_channel_websock_encodeDaniel P. Berrange1-27/+44
Instead of requiring use of another Buffer, pass a struct iovec into qio_channel_websock_encode, which gives callers more flexibility in how they process data. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: get rid of qio_channel_websock_encode helper methodDaniel P. Berrange1-14/+6
The qio_channel_websock_encode method is only used in one place, everything else calls qio_channel_websock_encode_buffer directly. It can also be pushed up a level into the qio_channel_websock_writev method, since every other caller of qio_channel_websock_write_wire has already filled encoutput. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: simplify websocket ping reply handlingDaniel P. Berrange1-13/+15
We must ensure we don't get flooded with ping replies if the outbound channel is slow. Currently we do this by keeping the ping reply in a separate temporary buffer and only writing it if the encoutput buffer is completely empty. This is overly pessimistic, as it is reasonable to add a ping reply to the encoutput buffer even if it has previous data in it, as long as that previous data doesn't include a ping reply. To track this better, put the ping reply directly into the encoutput buffer, and then record the size of encoutput at this time in pong_remain. As we write encoutput to the underlying channel, we can decrement the pong_remain counter. Once it hits zero, we can accept further ping replies for transmission. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-16io: monitor encoutput buffer size from websocket GSourceDaniel P. Berrange1-2/+2
The websocket GSource is monitoring the size of the rawoutput buffer to determine if the channel can accepts more writes. The rawoutput buffer, however, is merely a temporary staging buffer before data is copied into the encoutput buffer. Thus its size will always be zero when the GSource runs. This flaw causes the encoutput buffer to grow without bound if the other end of the underlying data channel doesn't read data being sent. This can be seen with VNC if a client is on a slow WAN link and the guest OS is sending many screen updates. A malicious VNC client can act like it is on a slow link by playing a video in the guest and then reading data very slowly, causing QEMU host memory to expand arbitrarily. This issue is assigned CVE-2017-15268, publically reported in https://bugs.launchpad.net/qemu/+bug/1718964 Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: add trace events for websockets frame handlingDaniel P. Berrange1-5/+18
It is useful to trace websockets frame encoding/decoding when debugging problems. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Attempt to send websocket close messages to clientBrandon Carpenter1-3/+65
Make a best effort attempt to close websocket connections according to the RFC. Sends the close message, as room permits in the socket buffer, and immediately closes the socket. Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Reply to ping framesBrandon Carpenter1-22/+44
Add an immediate ping reply (pong) to the outgoing stream when a ping is received. Unsolicited pongs are ignored. Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Ignore websocket PING and PONG framesBrandon Carpenter1-4/+17
Keep pings and gratuitous pongs generated by web browsers from killing websocket connections. Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Allow empty websocket payloadBrandon Carpenter1-32/+30
Some browsers send pings/pongs with no payload, so allow empty payloads instead of closing the connection. Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Add support for fragmented websocket binary framesBrandon Carpenter1-8/+18
Allows fragmented binary frames by saving the previous opcode. Handles the case where an intermediary (i.e., web proxy) fragments frames originally sent unfragmented by the client. Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: Small updates in preparation for websocket changesBrandon Carpenter1-45/+19
Gets rid of unnecessary bit shifting and performs proper EOF checking to avoid a large number of repeated calls to recvmsg() when a client abruptly terminates a connection (bug fix). Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: use case insensitive check for Connection & Upgrade websock headersDaniel P. Berrange1-2/+2
When checking the value of the Connection and Upgrade HTTP headers the websock RFC (6455) requires the comparison to be case insensitive. The Connection value should be an exact match not a substring. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: include full error message in websocket handshake traceDaniel P. Berrange1-3/+4
When the websocket handshake fails it is useful to log the real error message via the trace points for debugging purposes. Fixes bug: #1715186 Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04io: send proper HTTP response for websocket errorsDaniel P. Berrange1-46/+139
When any error occurs while processing the websockets handshake, QEMU just terminates the connection abruptly. This is in violation of the HTTP specs and does not help the client understand what they did wrong. This is particularly bad when the client gives the wrong path, as a "404 Not Found" would be very helpful. Refactor the handshake code so that it always sends a response to the client unless there was an I/O error. Fixes bug: #1715186 Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-07-13websock: Don't try to set *errp directlyEduardo Habkost1-2/+2
Assigning directly to *errp is not valid, as errp may be NULL, &error_fatal, or &error_abort. Use error_propagate() instead. Cc: "Daniel P. Berrange" <berrange@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <20170608133906.12737-4-ehabkost@redhat.com> Reviewed-by: Manos Pitsidianakis <el13635@mail.ntua.gr> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-02-28io: fully parse & validate HTTP headers for websocket protocol handshakeDaniel P. Berrange1-42/+194
The current websockets protocol handshake code is very relaxed, just doing crude string searching across the HTTP header data. This causes it to both reject valid connections and fail to reject invalid connections. For example, according to the RFC 6455 it: - MUST reject any method other than "GET" - MUST reject any HTTP version less than "HTTP/1.1" - MUST reject Connection header without "Upgrade" listed - MUST reject Upgrade header which is not 'websocket' - MUST reject missing Host header - MUST treat HTTP header names as case insensitive To do all this validation correctly requires that we fully parse the HTTP headers, populating a data structure containing the header fields. After this change, we also reject any path other than '/' Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-02-28io: fix decoding when multiple websockets frames arrive at onceDaniel P. Berrange1-14/+14
The qio_channel_websock_read_wire() method will read upto 4096 bytes off the socket and then decode the websockets header and payload. The code was only decoding a single websockets frame, even if the buffered data contained multiple frames. This meant that decoding of subsequent frames was delayed until further input arrived on the socket. This backlog of delayed frames gets worse & worse over time. Symptom was that when connecting to the VNC server via the built-in websockets server, mouse/keyboard interaction would start out fine, but slowly get more & more delayed until it was unusable. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-01-23io: change the QIOTask callback signatureDaniel P. Berrange1-4/+4
Currently the QIOTaskFunc signature takes an Object * for the source, and an Error * for any error. We also need to be able to provide a result pointer. Rather than continue to add parameters to QIOTaskFunc, remove the existing ones and simply pass the QIOTask object instead. This has methods to access all the other data items required in the callback impl. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-10-26io: Introduce a qio_channel_set_feature() helperFelipe Franciosi1-1/+1
Testing QIOChannel feature support can be done with a helper called qio_channel_has_feature(). Setting feature support, however, was done manually with a logical OR. This patch introduces a new helper called qio_channel_set_feature() and makes use of it where applicable. Signed-off-by: Felipe Franciosi <felipe@nutanix.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-10-26io: Use qio_channel_has_feature() where applicableFelipe Franciosi1-1/+1
Parts of the code have been testing QIOChannel features directly with a logical AND. This patch makes it all consistent by using the qio_channel_has_feature() function to test if a feature is present. Signed-off-by: Felipe Franciosi <felipe@nutanix.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-08-03io: remove mistaken call to object_ref on QTaskDaniel P. Berrange1-2/+1
The QTask struct is just a standalone struct, not a QOM Object, so calling object_ref() on it is not appropriate. This results in mangling the 'destroy' field in the QTask struct, causing the later call to qtask_free() to try to call the function at address 0x1, with predictably segfault happy results. There is in fact no need for ref counting with QTask, as the call to qtask_abort() or qtask_complete() will automatically free associated memory. This fixes the crash shown in https://bugs.launchpad.net/qemu/+bug/1589923 Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-05-19qemu-common: stop including qemu/bswap.h from qemu-common.hPaolo Bonzini1-0/+1
Move it to the actual users. There are still a few includes of qemu/bswap.h in headers; removing them is left for future work. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-22include/qemu/osdep.h: Don't include qapi/error.hMarkus Armbruster1-0/+1
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the Error typedef. Since then, we've moved to include qemu/osdep.h everywhere. Its file comment explains: "To avoid getting into possible circular include dependencies, this file should not include any other QEMU headers, with the exceptions of config-host.h, compiler.h, os-posix.h and os-win32.h, all of which are doing a similar job to this file and are under similar constraints." qapi/error.h doesn't do a similar job, and it doesn't adhere to similar constraints: it includes qapi-types.h. That's in excess of 100KiB of crap most .c files don't actually need. Add the typedef to qemu/typedefs.h, and include that instead of qapi/error.h. Include qapi/error.h in .c files that need it and don't get it now. Include qapi-types.h in qom/object.h for uint16List. Update scripts/clean-includes accordingly. Update it further to match reality: replace config.h by config-target.h, add sysemu/os-posix.h, sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h comment quoted above similarly. This reduces the number of objects depending on qapi/error.h from "all of them" to less than a third. Unfortunately, the number depending on qapi-types.h shrinks only a little. More work is needed for that one. Signed-off-by: Markus Armbruster <armbru@redhat.com> [Fix compilation without the spice devel packages. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-02-04io: Clean up includesPeter Maydell1-0/+1
Clean up includes so that osdep.h is included first and headers which it implies are not included manually. This commit was created with scripts/clean-includes. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1454089805-5470-14-git-send-email-peter.maydell@linaro.org
2015-12-18io: add QIOChannelWebsock classDaniel P. Berrange1-0/+962
Add a QIOChannel subclass that can run the websocket protocol over the top of another QIOChannel instance. This initial implementation is only capable of acting as a websockets server. There is no support for acting as a websockets client yet. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>