[gvfs] daemon: Fix admin backend spawning



commit cb1c755a4a91e3e4e738adb1fb0dd7b4eaee130b
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Feb 15 09:25:36 2018 +0100

    daemon: Fix admin backend spawning
    
    pkexec fails on some systems with "Refusing to render service to dead
    parents.", which is caused by double forking when spawning the process.
    Let's prevent this by G_SPAWN_DO_NOT_REAP_CHILD flag and clean up
    manually using g_child_watch_add.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=793445

 daemon/mount.c |   34 ++++++++++++++++++++++++++++------
 1 files changed, 28 insertions(+), 6 deletions(-)
---
diff --git a/daemon/mount.c b/daemon/mount.c
index 192923e..e242666 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -398,12 +398,22 @@ spawn_mount_handle_spawned (GVfsDBusSpawner *object,
 }
 
 static void
+child_watch_cb (GPid pid,
+                gint status,
+                gpointer user_data)
+{
+  g_spawn_close_pid (pid);
+}
+
+static void
 spawn_mount (MountData *data)
 {
   char *exec;
   GError *error;
   GDBusConnection *connection;
   static int mount_id = 0;
+  gchar **argv = NULL;
+  GPid pid;
 
   data->spawned = TRUE;
   
@@ -448,13 +458,25 @@ spawn_mount (MountData *data)
                           " ",
                           data->obj_path,
                           NULL);
-      if (!g_spawn_command_line_async (exec, &error))
-       {
+
+      /* G_SPAWN_DO_NOT_REAP_CHILD is necessary for admin backend to prevent
+       * double forking causing pkexec failures, see:
+       * https://bugzilla.gnome.org/show_bug.cgi?id=793445
+       */
+      if (!g_shell_parse_argv (exec, NULL, &argv, &error) ||
+          !g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error))
+        {
           g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (data->spawner));
-         mount_finish (data, error);
-         g_error_free (error);
-       }
-      
+          mount_finish (data, error);
+          g_error_free (error);
+        }
+      else
+        {
+          g_child_watch_add (pid, child_watch_cb, NULL);
+        }
+
+      g_strfreev (argv);
+
       /* TODO: Add a timeout here to detect spawned app crashing */
       
       g_object_unref (connection);


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