From 5d088356a9473c06564bd2cef18ca370437a17bc Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 14 May 2019 17:42:29 +0200 Subject: [PATCH 2/2] dbus-environment: Make Setenv request synchronuous Currently there is a potential race condition where the Setenv request races further session startup. i.e. the clients that are started with --start on login may quit before the Setenv DBus call is delivered. This opens a theoretical race condition where gnome-session is already past the initialization phase when it serves the Setenv request. --- daemon/dbus/gkd-dbus-environment.c | 62 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/daemon/dbus/gkd-dbus-environment.c b/daemon/dbus/gkd-dbus-environment.c index 051de953..acf398b9 100644 --- a/daemon/dbus/gkd-dbus-environment.c +++ b/daemon/dbus/gkd-dbus-environment.c @@ -38,32 +38,13 @@ gkd_dbus_environment_cleanup (GDBusConnection *conn) /* Nothing to do here */ } -static void -on_setenv_reply (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GError *error = NULL; - GVariant *res; - - res = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); - - if (error != NULL) { - if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) - g_debug ("couldn't set environment variable in session: %s", error->message); - else - g_message ("couldn't set environment variable in session: %s", error->message); - g_error_free (error); - } - - g_clear_pointer (&res, g_variant_unref); -} - static void setenv_request (GDBusConnection *conn, const gchar *env) { const gchar *value; gchar *name; + GVariant *res; + GError *error = NULL; /* Find the value part of the environment variable */ value = strchr (env, '='); @@ -73,19 +54,36 @@ setenv_request (GDBusConnection *conn, const gchar *env) name = g_strndup (env, value - env); ++value; - g_dbus_connection_call (conn, - SERVICE_SESSION_MANAGER, - PATH_SESSION_MANAGER, - IFACE_SESSION_MANAGER, - "Setenv", - g_variant_new ("(ss)", - name, - value), - NULL, G_DBUS_CALL_FLAGS_NONE, - -1, NULL, - on_setenv_reply, NULL); + /* Note: This call does not neccessarily need to be a sync call. However + * under certain conditions the process will quit immediately + * after emitting the call. This ensures that we wait long enough + * for the message to be sent out (could also be done using + * g_dbus_connection_flush() in the exit handler when called with + * --start) and also ensures that gnome-session has processed the + * DBus message before possibly thinking that the startup of + * gnome-keyring has finished and continuing with forking the + * shell. */ + res = g_dbus_connection_call_sync (conn, + SERVICE_SESSION_MANAGER, + PATH_SESSION_MANAGER, + IFACE_SESSION_MANAGER, + "Setenv", + g_variant_new ("(ss)", + name, + value), + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + + if (error != NULL) { + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) + g_debug ("couldn't set environment variable in session: %s", error->message); + else + g_message ("couldn't set environment variable in session: %s", error->message); + g_error_free (error); + } g_free (name); + g_clear_pointer (&res, g_variant_unref); } static void -- 2.20.1