# This patch is created according to issue #271: # "Shouldn't add XDG_SESSION_ID to dbus and systemd activation environment" # (https://github.com/mate-desktop/mate-session-manager/issues/271) # # It ports the following commits / patches from GNOME git (https://github.com/GNOME/gnome-session): # # - 646b9bc (28.8.2019) - util: Blacklist some session-specific variables # (https://github.com/GNOME/gnome-session/commit/646b9bc): # Things like XDG_SESSION_ID should not be uploaded to the environment. # For example this is broken currently: # # 1. SSH to your machine # 2. Log in to GNOME Shell # 3. Log out # 4. Log in again # 5. Lock the screen # 6. Try to unlock # # You can't, and this is because the XDG_SESSION_ID from the first session # (step 2) has leaked through to the second one (step 4), and so GNOME # Shell is listening to the `logind` `UnlockSession` signal for the wrong # session. The SSH session established in step 1 serves to keep the # `systemd --user` instance alive, so that the state is not torn down # between logins. # # - 9d8b070 (19.9.2019) - util: Blacklist NOTIFY_SOCKET # (https://github.com/GNOME/gnome-session/commit/9d8b070): # The NOTIFY_SOCKET environment variable was leaking into systemd # managed GNOME sessions and breaking things like OCI container runtimes # (eg., runc and crun) [1]. This variable is absent in non-systemd # managed sessions. # # [1] https://bugzilla.redhat.com/show_bug.cgi?id=1753328 # # https://gitlab.gnome.org/GNOME/gnome-session/merge_requests/22 # # - b7b2462 (24.9.2019) - util: Unset some environment variables on systemd # (https://github.com/GNOME/gnome-session/commit/b7b2462): # Variables like GNOME_SHELL_SESSION_MODE may not always be set at login, # causing them to survive between session. Add a list of variables that # need to be unset, and explicitly unset them on the systemd side. # # The list is taken from GDMs list of variables. # # - d44888f (29.3.2021) - util: Remove undesired variables from activation environment # (https://github.com/GNOME/gnome-session/commit/d44888fb): # Commit 646b9bc (included in 3.33.92) prevented one run of gnome-session # from uploading environment variables into `systemd --user` that should not # leak into a different login session, such as XDG_SESSION_ID. However, # non-GNOME session managers (and in particular the forks of gnome-session # found in Cinnamon and MATE) might still upload those environment variables. # # The other session managers should be fixed, similar to 646b9bc, but we # can mitigate this for GNOME sessions by actively unsetting the undesired # variables, instead of just not setting them. # # Signed-off-by: Simon McVittie # Resolves: https://gitlab.gnome.org/GNOME/gnome-session/-/issues/86 # diff -up mate-session-manager-f56f8cd/mate-session/gsm-util.c~ mate-session-manager-f56f8cd/mate-session/gsm-util.c --- mate-session-manager-f56f8cd/mate-session/gsm-util.c~ 2021-05-16 10:42:22.783785314 +0200 +++ mate-session-manager-f56f8cd/mate-session/gsm-util.c 2021-05-16 10:42:22.806785464 +0200 @@ -38,6 +38,37 @@ static gchar *_saved_session_dir = NULL; +/* These are variables that will not be passed on to subprocesses + * (either directly, via systemd or DBus). + * Some of these are blacklisted as they might end up in the wrong session + * (e.g. XDG_VTNR), others because they simply must never be passed on + * (NOTIFY_SOCKET). + */ +static const char * const variable_blacklist[] = { + "NOTIFY_SOCKET", + "XDG_SEAT", + "XDG_SESSION_ID", + "XDG_VTNR", + NULL +}; + +/* The following is copied from GDMs spawn_session function. + * + * Environment variables listed here will be copied into the user's service + * environments if they are set in gnome-session's environment. If they are + * not set in gnome-session's environment, they will be removed from the + * service environments. This is to protect against environment variables + * leaking from previous sessions (e.g. when switching from classic to + * default GNOME $GNOME_SHELL_SESSION_MODE will become unset). + */ +static const char * const variable_unsetlist[] = { + "DISPLAY", + "XAUTHORITY", + "WAYLAND_DISPLAY", + "WAYLAND_SOCKET", + NULL +}; + gchar ** gsm_get_screen_locker_command (void) { @@ -536,6 +567,9 @@ gsm_util_export_activation_environment ( const char *entry_name = entry_names[i]; const char *entry_value = g_getenv (entry_name); + if (g_strv_contains (variable_blacklist, entry_name)) + continue; + if (!g_utf8_validate (entry_name, -1, NULL)) continue; @@ -603,8 +637,23 @@ gsm_util_export_user_environment (GError return FALSE; } - g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); - for (entries = g_get_environ (); entries[i] != NULL; i++) { + entries = g_get_environ (); + + for (i = 0; variable_blacklist[i] != NULL; i++) + entries = g_environ_unsetenv (entries, variable_blacklist[i]); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(asas)")); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("as")); + for (i = 0; variable_unsetlist[i] != NULL; i++) + g_variant_builder_add (&builder, "s", variable_unsetlist[i]); + for (i = 0; variable_blacklist[i] != NULL; i++) + g_variant_builder_add (&builder, "s", variable_blacklist[i]); + g_variant_builder_close (&builder); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("as")); + + for (i = 0; entries[i] != NULL; i++) { const char *entry = entries[i]; if (!g_utf8_validate (entry, -1, NULL)) @@ -615,6 +664,7 @@ gsm_util_export_user_environment (GError g_variant_builder_add (&builder, "s", entry); } + g_variant_builder_close (&builder); g_regex_unref (regex); g_strfreev (entries); @@ -623,9 +673,8 @@ gsm_util_export_user_environment (GError "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "SetEnvironment", - g_variant_new ("(@as)", - g_variant_builder_end (&builder)), + "UnsetAndSetEnvironment", + g_variant_builder_end (&builder), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &bus_error);