[PATCH v2] socket: websocket refresh of max_size outside of poll

Anisse Astier posted 1 patch 4 years, 4 months ago
Test asan passed
Test checkpatch passed
Test FreeBSD passed
Test docker-mingw@fedora passed
Test docker-clang@ubuntu passed
Test docker-quick@centos7 passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20191206085057.15612-1-aastier@freebox.fr
Maintainers: "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
chardev/char-socket.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH v2] socket: websocket refresh of max_size outside of poll
Posted by Anisse Astier 4 years, 4 months ago
Because serial backend readiness isn't checked, the socket frontend (in
websocket mode) would send new characters before previous characters
were consumed. This lead to skipped characters, or worse, SysRq keys
being triggered.

This patch ensures the readable size is refreshed before consuming any
data. Normally, this size is refreshed in the event loop by the glib
prepare io_watch_poll_prepare calling tcp_chr_read_poll; but since the
websocket reader is a greedy because it needs a buffer to decode the
websocket protocol, (whereas tcp one ready bytes as necessary), there's
nothing to read or poll, so the max_size wouldn't be refreshed.

Buglink: https://bugs.launchpad.net/qemu/+bug/1828608
Signed-off-by: Anisse Astier <aastier@freebox.fr>
---
Changes since v1:
 - style changes

---
 chardev/char-socket.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 185fe38dda..9267ecd813 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -505,6 +505,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
     uint8_t buf[CHR_READ_BUF_LEN];
     int len, size;
 
+    if (s->is_websock)
+        /* Buffered greedy reader needs max_size refresh */
+        s->max_size = qemu_chr_be_can_write(chr);
     if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
         s->max_size <= 0) {
         return TRUE;
-- 
2.20.1