From 15a19ac7856c539aa9cfbf76997d18b0275aae35 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Mon, 4 Feb 2019 15:12:38 +0000 Subject: [PATCH 4/4] GdmManager: Don't perform timed login if session gets started At the moment it's possible for the login screen to initiate a timed login operation shortly after a user successfully starts their session. GDM won't complete the timed login operation, since a session is already running, but will erroneously overwrite the username associated with the session, misattributing the users session to the timed login user. Later, attempts to log in as the timed user will instead unlock the session for the other user, since that session is now associated with the timed login user. This commit refuses timed login requests on sessions that are already running, so the username doesn't get corrupted. CVE-2019-3825 Closes https://gitlab.gnome.org/GNOME/gdm/issues/460 --- daemon/gdm-manager.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index 0cc06a978..056560b20 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -2116,60 +2116,68 @@ on_session_client_ready_for_session_to_start (GdmSession *session, } else { g_debug ("GdmManager: Will start session when ready and told"); } waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), "waiting-to-start")); g_object_set_data (G_OBJECT (session), "start-when-ready", GINT_TO_POINTER (client_is_ready)); if (client_is_ready && waiting_to_start_user_session) { start_user_session_if_ready (manager, session, service_name); } } static void on_session_client_connected (GdmSession *session, GCredentials *credentials, GPid pid_of_client, GdmManager *manager) { GdmDisplay *display; char *username; int delay; gboolean enabled; gboolean allow_timed_login = FALSE; g_debug ("GdmManager: client with pid %d connected", (int) pid_of_client); + if (gdm_session_is_running (session)) { + const char *session_username; + session_username = gdm_session_get_username (session); + g_debug ("GdmManager: ignoring connection, since session already running (for user %s)", + session_username); + return; + } + display = get_display_for_user_session (session); if (display == NULL) { return; } if (!display_is_on_seat0 (display)) { return; } #ifdef WITH_PLYMOUTH if (manager->priv->plymouth_is_running) { plymouth_quit_with_transition (); manager->priv->plymouth_is_running = FALSE; } #endif g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL); if (!allow_timed_login) { return; } enabled = get_timed_login_details (manager, &username, &delay); if (! enabled) { return; } gdm_session_set_timed_login_details (session, username, delay); -- 2.21.0