From 975d10c9ef5d843764de83f0ecabb1fa8d903124 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Thu, 24 Aug 2017 14:33:03 +0100 Subject: [PATCH] red-qxl: Avoid using dangling pointers to RedClient A RedClient can be freed from the main thread following a main channel disconnection (reds_client_disconnect). This can happen while another thread is allocating a new channel client for that client. To prevent the usage of a pointer which can be invalid take ownership of the pointer. Note that we don't need this when disconnecting as disconnection is done synchronously (the dispatch messages are registered with DISPATCH_ACK). Signed-off-by: Frediano Ziglio Acked-by: Christophe Fergeau --- server/red-qxl.c | 8 ++++++-- server/red-worker.c | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/server/red-qxl.c b/server/red-qxl.c index 53f3338b..e145ea49 100644 --- a/server/red-qxl.c +++ b/server/red-qxl.c @@ -83,7 +83,9 @@ static void red_qxl_set_display_peer(RedChannel *channel, RedClient *client, spice_debug("%s", ""); dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher"); - payload.client = client; + // get a reference potentially the main channel can be destroyed in + // the main thread causing RedClient to be destroyed before using it + payload.client = g_object_ref(client); payload.stream = stream; payload.migration = migration; red_channel_capabilities_init(&payload.caps, caps); @@ -141,7 +143,9 @@ static void red_qxl_set_cursor_peer(RedChannel *channel, RedClient *client, Reds RedWorkerMessageCursorConnect payload = {0,}; Dispatcher *dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher"); spice_printerr(""); - payload.client = client; + // get a reference potentially the main channel can be destroyed in + // the main thread causing RedClient to be destroyed before using it + payload.client = g_object_ref(client); payload.stream = stream; payload.migration = migration; red_channel_capabilities_init(&payload.caps, caps); diff --git a/server/red-worker.c b/server/red-worker.c index 7db424c8..0e2e8fa3 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -729,6 +729,7 @@ static void handle_dev_display_connect(void *opaque, void *payload) dcc = dcc_new(display, msg->client, msg->stream, msg->migration, &msg->caps, worker->image_compression, worker->jpeg_state, worker->zlib_glz_state); + g_object_unref(msg->client); red_channel_capabilities_reset(&msg->caps); if (!dcc) { return; @@ -821,6 +822,7 @@ static void handle_dev_cursor_connect(void *opaque, void *payload) cursor_channel_connect(worker->cursor_channel, msg->client, msg->stream, msg->migration, &msg->caps); + g_object_unref(msg->client); red_channel_capabilities_reset(&msg->caps); }