[gdm] daemon: driveby XDMCP crash fix



commit 38ffd450c5a3e0bfe784294a81329dcdf443fb1f
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jul 13 15:15:47 2012 -0400

    daemon: driveby XDMCP crash fix
    
    If the XDMCP chooser exits enough times,
    the whole daemon eventually tanks when
    the child watch function tries to access
    freed memory.
    
    This commit takes the hammer approach of
    adding a reference to the slave from
    the child watch func.
    
    It also makes sure that there isn't ever
    two slaves running for one display at the
    same time.

 daemon/gdm-display.c     |    2 ++
 daemon/gdm-slave-proxy.c |   18 +++++++++++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)
---
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index e885bdf..be1d5e0 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -995,6 +995,8 @@ gdm_display_dispose (GObject *object)
         }
 
         if (display->priv->slave_proxy != NULL) {
+                gdm_slave_proxy_stop (display->priv->slave_proxy);
+
                 g_object_unref (display->priv->slave_proxy);
                 display->priv->slave_proxy = NULL;
         }
diff --git a/daemon/gdm-slave-proxy.c b/daemon/gdm-slave-proxy.c
index 68eddcb..ea373f7 100644
--- a/daemon/gdm-slave-proxy.c
+++ b/daemon/gdm-slave-proxy.c
@@ -197,6 +197,13 @@ spawn_command_line_async (const char *command_line,
         return ret;
 }
 
+static void
+clear_child_watch (GdmSlaveProxy *slave)
+{
+        slave->priv->child_watch_id = 0;
+        g_object_unref (slave);
+}
+
 static gboolean
 spawn_slave (GdmSlaveProxy *slave)
 {
@@ -219,9 +226,12 @@ spawn_slave (GdmSlaveProxy *slave)
 
         g_debug ("GdmSlaveProxy: Started slave with pid %d", slave->priv->pid);
 
-        slave->priv->child_watch_id = g_child_watch_add (slave->priv->pid,
-                                                         (GChildWatchFunc)child_watch,
-                                                         slave);
+        slave->priv->child_watch_id = g_child_watch_add_full (G_PRIORITY_DEFAULT,
+                                                              slave->priv->pid,
+                                                              (GChildWatchFunc)child_watch,
+                                                              g_object_ref (slave),
+                                                              (GDestroyNotify)
+                                                              clear_child_watch);
 
         result = TRUE;
 
@@ -257,6 +267,8 @@ kill_slave (GdmSlaveProxy *slave)
 gboolean
 gdm_slave_proxy_start (GdmSlaveProxy *slave)
 {
+        gdm_slave_proxy_stop (slave);
+
         spawn_slave (slave);
 
         return TRUE;



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