diff options
| author | Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> | 2025-06-03 18:18:28 +0900 |
|---|---|---|
| committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2025-07-14 14:50:44 +0400 |
| commit | aef22331b5a4670f42638a5f63a26e93bf779aae (patch) | |
| tree | 10aa3913e7e991f1bc1808c590d7dcd3f6b978db /ui/vnc.c | |
| parent | 9a4e273ddec3927920c5958d2226c6b38b543336 (diff) | |
| download | focaccia-qemu-aef22331b5a4670f42638a5f63a26e93bf779aae.tar.gz focaccia-qemu-aef22331b5a4670f42638a5f63a26e93bf779aae.zip | |
ui/vnc: Do not copy z_stream
vnc_worker_thread_loop() copies z_stream stored in its local VncState to
the persistent VncState, and the copied one is freed with deflateEnd()
later. However, deflateEnd() refuses to operate with a copied z_stream
and returns Z_STREAM_ERROR, leaking the allocated memory.
Avoid copying the zlib state to fix the memory leak.
Fixes: bd023f953e5e ("vnc: threaded VNC server")
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20250603-zlib-v3-1-20b857bd8d05@rsg.ci.i.u-tokyo.ac.jp>
Diffstat (limited to 'ui/vnc.c')
| -rw-r--r-- | ui/vnc.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/ui/vnc.c b/ui/vnc.c index e9c30aad62..ab74154e4c 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -56,6 +56,11 @@ #include "io/dns-resolver.h" #include "monitor/monitor.h" +typedef struct VncConnection { + VncState vs; + VncZlib zlib; +} VncConnection; + #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT #define VNC_REFRESH_INTERVAL_INC 50 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE @@ -1362,7 +1367,7 @@ void vnc_disconnect_finish(VncState *vs) vs->magic = 0; g_free(vs->zrle); g_free(vs->tight); - g_free(vs); + g_free(container_of(vs, VncConnection, vs)); } size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err) @@ -3241,11 +3246,13 @@ static void vnc_refresh(DisplayChangeListener *dcl) static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, bool skipauth, bool websocket) { - VncState *vs = g_new0(VncState, 1); + VncConnection *vc = g_new0(VncConnection, 1); + VncState *vs = &vc->vs; bool first_client = QTAILQ_EMPTY(&vd->clients); int i; trace_vnc_client_connect(vs, sioc); + vs->zlib = &vc->zlib; vs->zrle = g_new0(VncZrle, 1); vs->tight = g_new0(VncTight, 1); vs->magic = VNC_MAGIC; @@ -3268,7 +3275,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, #ifdef CONFIG_PNG buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc); #endif - buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc); + buffer_init(&vc->zlib.zlib, "vnc-zlib/%p", sioc); buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc); buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc); buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc); |