[evolution-data-server] Possible use-after-free on factory subprocess close



commit 8568699c073a8bdeec2f11f98bbea043c0405ac2
Author: Milan Crha <mcrha redhat com>
Date:   Wed Apr 27 19:55:00 2016 +0200

    Possible use-after-free on factory subprocess close
    
    There could happen that the 'loop' variable had been used after it
    was freed in the main(), due to the subprocess_backend_handle_close_cb()
    being invoked after the vanished_cb() callback.

 .../evolution-addressbook-factory-subprocess.c     |   16 ++++++++++------
 .../evolution-calendar-factory-subprocess.c        |   16 ++++++++++------
 2 files changed, 20 insertions(+), 12 deletions(-)
---
diff --git a/addressbook/libedata-book/evolution-addressbook-factory-subprocess.c 
b/addressbook/libedata-book/evolution-addressbook-factory-subprocess.c
index 53daeb5..e0eaf44 100644
--- a/addressbook/libedata-book/evolution-addressbook-factory-subprocess.c
+++ b/addressbook/libedata-book/evolution-addressbook-factory-subprocess.c
@@ -53,11 +53,14 @@ static GOptionEntry entries[] = {
 
 static void
 prepare_shutdown_and_quit (ESubprocessBookFactory *subprocess_book_factory,
-                          GMainLoop *loop)
+                          SubprocessData *sd)
 {
        e_subprocess_factory_call_backends_prepare_shutdown (E_SUBPROCESS_FACTORY (subprocess_book_factory));
 
-       g_main_loop_quit (loop);
+       if (sd->loop) {
+               g_main_loop_quit (sd->loop);
+               sd->loop = NULL;
+       }
 }
 
 static gboolean
@@ -99,7 +102,7 @@ subprocess_backend_handle_close_cb (EDBusSubprocessBackend *proxy,
                                    GDBusMethodInvocation *invocation,
                                    SubprocessData *sd)
 {
-       prepare_shutdown_and_quit (sd->subprocess_book_factory, sd->loop);
+       prepare_shutdown_and_quit (sd->subprocess_book_factory, sd);
 
        return TRUE;
 }
@@ -139,7 +142,7 @@ vanished_cb (GDBusConnection *connection,
             const gchar *name,
             SubprocessData *sd)
 {
-       prepare_shutdown_and_quit (sd->subprocess_book_factory, sd->loop);
+       prepare_shutdown_and_quit (sd->subprocess_book_factory, sd);
 }
 
 gint
@@ -214,12 +217,13 @@ main (gint argc,
                NULL);
 
        g_main_loop_run (loop);
+
        g_bus_unown_name (id);
-       g_main_loop_unref (loop);
+       g_bus_unwatch_name (watched_id);
 
        g_clear_object (&subprocess_book_factory);
        g_clear_object (&manager);
-       g_bus_unwatch_name (watched_id);
+       g_main_loop_unref (loop);
 
        return 0;
 }
diff --git a/calendar/libedata-cal/evolution-calendar-factory-subprocess.c 
b/calendar/libedata-cal/evolution-calendar-factory-subprocess.c
index e996a45..877f6c1 100644
--- a/calendar/libedata-cal/evolution-calendar-factory-subprocess.c
+++ b/calendar/libedata-cal/evolution-calendar-factory-subprocess.c
@@ -50,11 +50,14 @@ static GOptionEntry entries[] = {
 
 static void
 prepare_shutdown_and_quit (ESubprocessCalFactory *subprocess_cal_factory,
-                          GMainLoop *loop)
+                          SubprocessData *sd)
 {
        e_subprocess_factory_call_backends_prepare_shutdown (E_SUBPROCESS_FACTORY (subprocess_cal_factory));
 
-       g_main_loop_quit (loop);
+       if (sd->loop) {
+               g_main_loop_quit (sd->loop);
+               sd->loop = NULL;
+       }
 }
 
 static gboolean
@@ -96,7 +99,7 @@ subprocess_backend_handle_close_cb (EDBusSubprocessBackend *proxy,
                                    GDBusMethodInvocation *invocation,
                                    SubprocessData *sd)
 {
-       prepare_shutdown_and_quit (sd->subprocess_cal_factory, sd->loop);
+       prepare_shutdown_and_quit (sd->subprocess_cal_factory, sd);
 
        return TRUE;
 }
@@ -136,7 +139,7 @@ vanished_cb (GDBusConnection *connection,
             const gchar *name,
             SubprocessData *sd)
 {
-       prepare_shutdown_and_quit (sd->subprocess_cal_factory, sd->loop);
+       prepare_shutdown_and_quit (sd->subprocess_cal_factory, sd);
 }
 
 gint
@@ -211,12 +214,13 @@ main (gint argc,
                NULL);
 
        g_main_loop_run (loop);
+
        g_bus_unown_name (id);
-       g_main_loop_unref (loop);
+       g_bus_unwatch_name (watched_id);
 
        g_clear_object (&subprocess_cal_factory);
        g_clear_object (&manager);
-       g_bus_unwatch_name (watched_id);
+       g_main_loop_unref (loop);
 
        return 0;
 }


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