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