Blame SOURCES/0003-session-Don-t-allow-greeter-operations-on-an-running.patch

4dd5a8
From 7b83c1dc9645cabadfeb253d7eca427f6a26d10f Mon Sep 17 00:00:00 2001
4dd5a8
From: Iain Lane <iainl@gnome.org>
4dd5a8
Date: Thu, 31 Jan 2019 17:51:52 +0000
4dd5a8
Subject: [PATCH 3/4] session: Don't allow greeter operations on an running
4dd5a8
 session
4dd5a8
4dd5a8
If a client has a reference to a session that starts running,
4dd5a8
refuse to allow further operations on the session.
4dd5a8
4dd5a8
CVE-2019-3825
4dd5a8
---
4dd5a8
 daemon/gdm-session.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
4dd5a8
 1 file changed, 75 insertions(+)
4dd5a8
4dd5a8
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
4dd5a8
index f23a83c5e..a8263ba11 100644
4dd5a8
--- a/daemon/gdm-session.c
4dd5a8
+++ b/daemon/gdm-session.c
4dd5a8
@@ -1401,130 +1401,205 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier    *u
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_answer_query (GdmDBusUserVerifier    *user_verifier_interface,
4dd5a8
                                         GDBusMethodInvocation  *invocation,
4dd5a8
                                         const char             *service_name,
4dd5a8
                                         const char             *answer,
4dd5a8
                                         GdmSession             *self)
4dd5a8
 {
4dd5a8
         gdm_dbus_user_verifier_complete_answer_query (user_verifier_interface,
4dd5a8
                                                       invocation);
4dd5a8
         gdm_session_answer_query (self, service_name, answer);
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_cancel (GdmDBusUserVerifier    *user_verifier_interface,
4dd5a8
                                   GDBusMethodInvocation  *invocation,
4dd5a8
                                   GdmSession             *self)
4dd5a8
 {
4dd5a8
         gdm_dbus_user_verifier_complete_cancel (user_verifier_interface,
4dd5a8
                                                 invocation);
4dd5a8
         gdm_session_cancel (self);
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_select_session (GdmDBusGreeter         *greeter_interface,
4dd5a8
                                           GDBusMethodInvocation  *invocation,
4dd5a8
                                           const char             *session,
4dd5a8
                                           GdmSession             *self)
4dd5a8
 {
4dd5a8
+        if (gdm_session_is_running (self)) {
4dd5a8
+                const char *username;
4dd5a8
+
4dd5a8
+                username = gdm_session_get_username (self);
4dd5a8
+                g_debug ("GdmSession: refusing to select session %s since it's already running (for user %s)",
4dd5a8
+                         session,
4dd5a8
+                         username);
4dd5a8
+                g_dbus_method_invocation_return_error (invocation,
4dd5a8
+                                                       G_DBUS_ERROR,
4dd5a8
+                                                       G_DBUS_ERROR_INVALID_ARGS,
4dd5a8
+                                                       "Session already running for user %s",
4dd5a8
+                                                       username);
4dd5a8
+                return TRUE;
4dd5a8
+        }
4dd5a8
+
4dd5a8
         if (self->priv->greeter_interface != NULL) {
4dd5a8
                 gdm_dbus_greeter_complete_select_session (greeter_interface,
4dd5a8
                                                           invocation);
4dd5a8
         }
4dd5a8
         gdm_session_select_session (self, session);
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_select_user (GdmDBusGreeter        *greeter_interface,
4dd5a8
                                        GDBusMethodInvocation *invocation,
4dd5a8
                                        const char            *username,
4dd5a8
                                        GdmSession            *self)
4dd5a8
 {
4dd5a8
+        if (gdm_session_is_running (self)) {
4dd5a8
+                const char *session_username;
4dd5a8
+
4dd5a8
+                session_username = gdm_session_get_username (self);
4dd5a8
+                g_debug ("GdmSession: refusing to select user %s, since session (%p) already running (for user %s)",
4dd5a8
+                          username,
4dd5a8
+                          self,
4dd5a8
+                          session_username);
4dd5a8
+                g_dbus_method_invocation_return_error (invocation,
4dd5a8
+                                                       G_DBUS_ERROR,
4dd5a8
+                                                       G_DBUS_ERROR_INVALID_ARGS,
4dd5a8
+                                                       "Session already running for user %s",
4dd5a8
+                                                       session_username);
4dd5a8
+                return TRUE;
4dd5a8
+        }
4dd5a8
+
4dd5a8
         if (self->priv->greeter_interface != NULL) {
4dd5a8
                 gdm_dbus_greeter_complete_select_user (greeter_interface,
4dd5a8
                                                        invocation);
4dd5a8
         }
4dd5a8
         g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self);
4dd5a8
         gdm_session_select_user (self, username);
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter        *greeter_interface,
4dd5a8
                                                     GDBusMethodInvocation *invocation,
4dd5a8
                                                     const char            *service_name,
4dd5a8
                                                     gboolean               client_is_ready,
4dd5a8
                                                     GdmSession            *self)
4dd5a8
 {
4dd5a8
+        if (gdm_session_is_running (self)) {
4dd5a8
+                const char *username;
4dd5a8
+
4dd5a8
+                username = gdm_session_get_username (self);
4dd5a8
+                g_debug ("GdmSession: refusing to start session (%p), since it's already running (for user %s)",
4dd5a8
+                         self,
4dd5a8
+                         username);
4dd5a8
+                g_dbus_method_invocation_return_error (invocation,
4dd5a8
+                                                       G_DBUS_ERROR,
4dd5a8
+                                                       G_DBUS_ERROR_INVALID_ARGS,
4dd5a8
+                                                       "Session already running for user %s",
4dd5a8
+                                                       username);
4dd5a8
+                return TRUE;
4dd5a8
+        }
4dd5a8
 
4dd5a8
         if (self->priv->greeter_interface != NULL) {
4dd5a8
                 gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface,
4dd5a8
                                                                     invocation);
4dd5a8
         }
4dd5a8
         g_signal_emit (G_OBJECT (self),
4dd5a8
                        signals [CLIENT_READY_FOR_SESSION_TO_START],
4dd5a8
                        0,
4dd5a8
                        service_name,
4dd5a8
                        client_is_ready);
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_get_timed_login_details (GdmDBusGreeter        *greeter_interface,
4dd5a8
                                             GDBusMethodInvocation *invocation,
4dd5a8
                                             GdmSession            *self)
4dd5a8
 {
4dd5a8
+        if (gdm_session_is_running (self)) {
4dd5a8
+                const char *username;
4dd5a8
+
4dd5a8
+                username = gdm_session_get_username (self);
4dd5a8
+                g_debug ("GdmSession: refusing to give timed login details, session (%p) already running (for user %s)",
4dd5a8
+                         self,
4dd5a8
+                         username);
4dd5a8
+                g_dbus_method_invocation_return_error (invocation,
4dd5a8
+                                                       G_DBUS_ERROR,
4dd5a8
+                                                       G_DBUS_ERROR_INVALID_ARGS,
4dd5a8
+                                                       "Session already running for user %s",
4dd5a8
+                                                       username);
4dd5a8
+                return TRUE;
4dd5a8
+        }
4dd5a8
 
4dd5a8
         if (self->priv->greeter_interface != NULL) {
4dd5a8
                 gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface,
4dd5a8
                                                                    invocation,
4dd5a8
                                                                    self->priv->timed_login_username != NULL,
4dd5a8
                                                                    self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
4dd5a8
                                                                    self->priv->timed_login_delay);
4dd5a8
                 if (self->priv->timed_login_username != NULL) {
4dd5a8
                         gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
4dd5a8
                                                                      self->priv->timed_login_username,
4dd5a8
                                                                      self->priv->timed_login_delay);
4dd5a8
                 }
4dd5a8
         }
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_session_handle_client_begin_auto_login (GdmDBusGreeter        *greeter_interface,
4dd5a8
                                             GDBusMethodInvocation *invocation,
4dd5a8
                                             const char            *username,
4dd5a8
                                             GdmSession            *self)
4dd5a8
 {
4dd5a8
+        const char *session_username;
4dd5a8
+
4dd5a8
+        if (gdm_session_is_running (self)) {
4dd5a8
+                session_username = gdm_session_get_username (self);
4dd5a8
+                g_debug ("GdmSession: refusing auto login operation, session (%p) already running for user %s (%s requested)",
4dd5a8
+                         self,
4dd5a8
+                         session_username,
4dd5a8
+                         username);
4dd5a8
+                g_dbus_method_invocation_return_error (invocation,
4dd5a8
+                                                       G_DBUS_ERROR,
4dd5a8
+                                                       G_DBUS_ERROR_INVALID_ARGS,
4dd5a8
+                                                       "Session already owned by user %s",
4dd5a8
+                                                       session_username);
4dd5a8
+                return TRUE;
4dd5a8
+        }
4dd5a8
+
4dd5a8
         if (self->priv->greeter_interface != NULL) {
4dd5a8
                 gdm_dbus_greeter_complete_begin_auto_login (greeter_interface,
4dd5a8
                                                             invocation);
4dd5a8
         }
4dd5a8
 
4dd5a8
         g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)",
4dd5a8
                  username,
4dd5a8
                  gdm_session_get_session_id (self),
4dd5a8
                  self);
4dd5a8
 
4dd5a8
         gdm_session_setup_for_user (self, "gdm-autologin", username);
4dd5a8
 
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static void
4dd5a8
 export_user_verifier_interface (GdmSession      *self,
4dd5a8
                                 GDBusConnection *connection)
4dd5a8
 {
4dd5a8
         GdmDBusUserVerifier   *user_verifier_interface;
4dd5a8
         user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ());
4dd5a8
 
4dd5a8
         g_object_set_data (G_OBJECT (connection), "gdm-session", self);
4dd5a8
 
4dd5a8
         g_signal_connect (user_verifier_interface,
4dd5a8
                           "handle-enable-extensions",
4dd5a8
                           G_CALLBACK (gdm_session_handle_client_enable_extensions),
4dd5a8
                           connection);
4dd5a8
         g_signal_connect (user_verifier_interface,
4dd5a8
                           "handle-begin-verification",
4dd5a8
-- 
4dd5a8
2.21.0
4dd5a8