mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-02 22:52:26 +00:00
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@redhat.com> Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
This commit is contained in:
parent
b12187b332
commit
e7c79b71a4
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user