[Spice-devel] [PATCH spice-server v2] red-worker: Fix leak processing update commands
Frediano Ziglio
fziglio at redhat.com
Mon Sep 4 15:38:59 UTC 2017
Is possible to have a leak processing update commands if
the update command is synchronous and the rectangle list
is empty. Note that Qemu always pass an empty list.
If the list is empty display_channel_update fill the list.
This is used to send back the list in case of asynchronous
requests. But in handle_dev_update_async (the callback that
handle the asynchronous case) the list is correctly freed.
This was discovered by accident looking at the code.
Reproduced with a Windows recording file using GCC address
sanitizer and this patch to spice-server-replay:
--- a/server/red-replay-qxl.c
+++ b/server/red-replay-qxl.c
@@ -1280,7 +1280,10 @@ static void replay_handle_dev_input(QXLWorker *worker, SpiceReplay *replay,
replay->created_primary = FALSE;
worker->destroy_surfaces(worker);
break;
- case RED_WORKER_MESSAGE_UPDATE:
+ case RED_WORKER_MESSAGE_UPDATE: {
+ QXLRect update = { 0, 0, 100, 100 };
+ worker->update_area(worker, 0, &update, NULL, 0, 0);
+ } break;
// XXX do anything? we record the correct bitmaps already.
case RED_WORKER_MESSAGE_DISPLAY_CONNECT:
// we want to ignore this one - it is sent on client connection, we
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/red-worker.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Changes since v1:
- indented patch in comment to avoid am problems.
diff --git a/server/red-worker.c b/server/red-worker.c
index 4d8566be..594dec55 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -437,13 +437,17 @@ static void handle_dev_update(void *opaque, void *payload)
{
RedWorker *worker = opaque;
RedWorkerMessageUpdate *msg = payload;
+ QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects;
spice_return_if_fail(worker->running);
flush_display_commands(worker);
display_channel_update(worker->display_channel,
msg->surface_id, msg->qxl_area, msg->clear_dirty_region,
- &msg->qxl_dirty_rects, &msg->num_dirty_rects);
+ &qxl_dirty_rects, &msg->num_dirty_rects);
+ if (msg->qxl_dirty_rects != qxl_dirty_rects) {
+ free(qxl_dirty_rects);
+ }
}
static void handle_dev_del_memslot(void *opaque, void *payload)
--
2.13.5
More information about the Spice-devel
mailing list