[Spice-commits] server/display-channel.c server/red-channel.c server/red-channel.h

Frediano Ziglio fziglio at kemper.freedesktop.org
Thu Dec 10 09:36:55 PST 2015


 server/display-channel.c |    8 ++++++--
 server/red-channel.c     |    6 ++----
 server/red-channel.h     |    2 ++
 3 files changed, 10 insertions(+), 6 deletions(-)

New commits:
commit e7c79b71a40a6340849caa7f9345e3c8a7075664
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Wed Dec 9 13:34:15 2015 +0000

    channel: make sure we retain RedChannelClient while processing it
    
    During display_channel_handle_migrate_data the pointer is passed
    to different functions which could release it making the pointer
    invalid. Make sure pointer is not freed while processing.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Jonathon Jongsma <jjongsma at redhat.com>

diff --git a/server/display-channel.c b/server/display-channel.c
index e3131e0..7cbcea5 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1190,6 +1190,7 @@ int display_channel_wait_for_migrate_data(DisplayChannel *display)
     uint64_t end_time = red_get_monotonic_time() + DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT;
     RedChannel *channel = &display->common.base;
     RedChannelClient *rcc;
+    int ret = FALSE;
 
     if (!red_channel_is_waiting_for_migrate_data(&display->common.base)) {
         return FALSE;
@@ -1200,6 +1201,7 @@ int display_channel_wait_for_migrate_data(DisplayChannel *display)
 
     rcc = SPICE_CONTAINEROF(ring_get_head(&channel->clients), RedChannelClient, channel_link);
 
+    red_channel_client_ref(rcc);
     for (;;) {
         red_channel_client_receive(rcc);
         if (!red_channel_client_is_connected(rcc)) {
@@ -1207,7 +1209,8 @@ int display_channel_wait_for_migrate_data(DisplayChannel *display)
         }
 
         if (!red_channel_client_is_waiting_for_migrate_data(rcc)) {
-            return TRUE;
+            ret = TRUE;
+            break;
         }
         if (red_get_monotonic_time() > end_time) {
             spice_warning("timeout");
@@ -1216,7 +1219,8 @@ int display_channel_wait_for_migrate_data(DisplayChannel *display)
         }
         usleep(DISPLAY_CLIENT_RETRY_INTERVAL);
     }
-    return FALSE;
+    red_channel_client_unref(rcc);
+    return ret;
 }
 
 void display_channel_flush_all_surfaces(DisplayChannel *display)
diff --git a/server/red-channel.c b/server/red-channel.c
index 4b1d426..7dfb9bf 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -116,8 +116,6 @@ static inline int red_channel_client_waiting_for_ack(RedChannelClient *rcc);
 */
 static void red_channel_ref(RedChannel *channel);
 static void red_channel_unref(RedChannel *channel);
-static void red_channel_client_ref(RedChannelClient *rcc);
-static void red_channel_client_unref(RedChannelClient *rcc);
 
 static uint32_t full_header_get_msg_size(SpiceDataHeaderOpaque *header)
 {
@@ -1231,12 +1229,12 @@ static void red_channel_unref(RedChannel *channel)
     }
 }
 
-static void red_channel_client_ref(RedChannelClient *rcc)
+void red_channel_client_ref(RedChannelClient *rcc)
 {
     rcc->refs++;
 }
 
-static void red_channel_client_unref(RedChannelClient *rcc)
+void red_channel_client_unref(RedChannelClient *rcc)
 {
     if (!--rcc->refs) {
         spice_debug("destroy rcc=%p", rcc);
diff --git a/server/red-channel.h b/server/red-channel.h
index 8206cec..2058350 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -418,6 +418,8 @@ int red_channel_is_waiting_for_migrate_data(RedChannel *channel);
 
 void red_channel_client_destroy(RedChannelClient *rcc);
 void red_channel_destroy(RedChannel *channel);
+void red_channel_client_ref(RedChannelClient *rcc);
+void red_channel_client_unref(RedChannelClient *rcc);
 
 int red_channel_client_test_remote_common_cap(RedChannelClient *rcc, uint32_t cap);
 int red_channel_client_test_remote_cap(RedChannelClient *rcc, uint32_t cap);


More information about the Spice-commits mailing list