From 94d9fec87960e3ff5f7b75dadcde2807db148fbd Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Thu, 31 Jan 2019 17:51:52 +0000 Subject: session: Don't allow greeter operations on an running session If a client has a reference to a session that starts running, refuse to allow further operations on the session. CVE-2019-3825 --- daemon/gdm-session.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index 09f47108..ca06608c 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -1414,6 +1414,21 @@ gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interf const char *session, GdmSession *self) { + if (gdm_session_is_running (self)) { + const char *username; + + username = gdm_session_get_username (self); + g_debug ("GdmSession: refusing to select session %s since it's already running (for user %s)", + session, + username); + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Session already running for user %s", + username); + return TRUE; + } + if (self->priv->greeter_interface != NULL) { gdm_dbus_greeter_complete_select_session (greeter_interface, invocation); @@ -1428,6 +1443,22 @@ gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface, const char *username, GdmSession *self) { + if (gdm_session_is_running (self)) { + const char *session_username; + + session_username = gdm_session_get_username (self); + g_debug ("GdmSession: refusing to select user %s, since session (%p) already running (for user %s)", + username, + self, + session_username); + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Session already running for user %s", + session_username); + return TRUE; + } + if (self->priv->greeter_interface != NULL) { gdm_dbus_greeter_complete_select_user (greeter_interface, invocation); @@ -1444,6 +1475,20 @@ gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greet gboolean client_is_ready, GdmSession *self) { + if (gdm_session_is_running (self)) { + const char *username; + + username = gdm_session_get_username (self); + g_debug ("GdmSession: refusing to start session (%p), since it's already running (for user %s)", + self, + username); + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Session already running for user %s", + username); + return TRUE; + } if (self->priv->greeter_interface != NULL) { gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface, @@ -1462,6 +1507,20 @@ gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_inter GDBusMethodInvocation *invocation, GdmSession *self) { + if (gdm_session_is_running (self)) { + const char *username; + + username = gdm_session_get_username (self); + g_debug ("GdmSession: refusing to give timed login details, session (%p) already running (for user %s)", + self, + username); + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Session already running for user %s", + username); + return TRUE; + } if (self->priv->greeter_interface != NULL) { gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface, @@ -1484,6 +1543,22 @@ gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_inter const char *username, GdmSession *self) { + const char *session_username; + + if (gdm_session_is_running (self)) { + session_username = gdm_session_get_username (self); + g_debug ("GdmSession: refusing auto login operation, session (%p) already running for user %s (%s requested)", + self, + session_username, + username); + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Session already owned by user %s", + session_username); + return TRUE; + } + if (self->priv->greeter_interface != NULL) { gdm_dbus_greeter_complete_begin_auto_login (greeter_interface, invocation); -- cgit v1.2.1