[spice PATCH 47/55] snd_channel: fix double release

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Due to the fix in the previous patch, snd_disconnect_channel can be
called both when there is write/read error in the channel, or from
red_client_destroy (which calls client_cbs.disconnect).
Multiple calls to snd_disconnect_channel resulted in calling
channel->cleanup(channel) more than once (double release).
---
 server/snd_worker.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/server/snd_worker.c b/server/snd_worker.c
index 2746940..bcf1452 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -219,15 +219,20 @@ static void snd_disconnect_channel(SndChannel *channel)
     SndWorker *worker;
 
     if (!channel) {
+        spice_debug("not connected");
         return;
     }
-    channel->cleanup(channel);
-    worker = channel->worker;
-    red_channel_client_disconnect(worker->connection->channel_client);
-    core->watch_remove(channel->stream->watch);
-    channel->stream->watch = NULL;
-    reds_stream_free(channel->stream);
-    spice_marshaller_destroy(channel->send_data.marshaller);
+    spice_debug("%p", channel);
+    if (channel->stream) {
+        channel->cleanup(channel);
+        worker = channel->worker;
+        red_channel_client_disconnect(worker->connection->channel_client);
+        core->watch_remove(channel->stream->watch);
+        channel->stream->watch = NULL;
+        reds_stream_free(channel->stream);
+        channel->stream = NULL;
+        spice_marshaller_destroy(channel->send_data.marshaller);
+    }
     snd_channel_put(channel);
 }
 
@@ -992,13 +997,15 @@ static void snd_disconnect_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
 
+    spice_debug(NULL);
     spice_assert(rcc->channel);
     spice_assert(rcc->channel->data);
     worker = (SndWorker *)rcc->channel->data;
 
-    spice_assert(worker->connection->channel_client == rcc);
-    snd_disconnect_channel(worker->connection);
-    spice_assert(worker->connection == NULL);
+    if (worker->connection) {
+        spice_assert(worker->connection->channel_client == rcc);
+        snd_disconnect_channel(worker->connection);
+    }
 }
 
 static void snd_set_command(SndChannel *channel, uint32_t command)
-- 
1.7.7.6

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]