[Spice-devel] [spice-gtk] Check coroutine_init() return value

Christophe Fergeau cfergeau at redhat.com
Mon Nov 18 09:00:16 PST 2013


coroutine_init() can fail, but spice-channel.c was not checking its return
value, which could lead to some crashes if coroutine_init() failed and we
then try to use coroutine_yieldto()
---
 gtk/coroutine.h          | 2 +-
 gtk/coroutine_ucontext.c | 6 ++++++
 gtk/spice-channel.c      | 9 ++++++++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gtk/coroutine.h b/gtk/coroutine.h
index 15b90b4..ef6f3db 100644
--- a/gtk/coroutine.h
+++ b/gtk/coroutine.h
@@ -56,7 +56,7 @@ struct coroutine
 };
 
 #define IN_MAIN_CONTEXT (coroutine_self() == NULL || coroutine_is_main_context(coroutine_self()))
-int coroutine_init(struct coroutine *co);
+int coroutine_init(struct coroutine *co) G_GNUC_WARN_UNUSED_RESULT;
 
 int coroutine_release(struct coroutine *co);
 
diff --git a/gtk/coroutine_ucontext.c b/gtk/coroutine_ucontext.c
index f4ff22e..f391f28 100644
--- a/gtk/coroutine_ucontext.c
+++ b/gtk/coroutine_ucontext.c
@@ -65,6 +65,12 @@ static void coroutine_trampoline(struct continuation *cc)
 
 int coroutine_init(struct coroutine *co)
 {
+    static int init_count = 1;
+    if (init_count % 10 == 0) {
+        g_warning("failing corouitne_init!!");
+        return -1;
+    }
+    init_count++;
 	if (co->stack_size == 0)
 		co->stack_size = 16 << 20;
 
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 41d5eab..d0b93f4 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2358,6 +2358,7 @@ static gboolean connect_delayed(gpointer data)
     SpiceChannel *channel = data;
     SpiceChannelPrivate *c = channel->priv;
     struct coroutine *co;
+    int inited;
 
     CHANNEL_DEBUG(channel, "Open coroutine starting %p", channel);
     c->connect_delayed_id = 0;
@@ -2368,7 +2369,13 @@ static gboolean connect_delayed(gpointer data)
     co->entry = spice_channel_coroutine;
     co->release = NULL;
 
-    coroutine_init(co);
+    inited = coroutine_init(co);
+    if (inited != 0) {
+        g_warning("Failed to initialize channel coroutine");
+        CHANNEL_DEBUG(channel, "coroutine_init failed");
+        g_object_unref(G_OBJECT(channel));
+        return FALSE;
+    }
     coroutine_yieldto(co, channel);
 
     return FALSE;
-- 
1.8.4.2



More information about the Spice-devel mailing list