import gdm-3.28.3-29.el8

This commit is contained in:
CentOS Sources 2020-04-28 05:35:31 -04:00 committed by Andrew Lukoshko
parent 1657319ce7
commit d44d7b3f2b
13 changed files with 2514 additions and 57 deletions

View File

@ -0,0 +1,135 @@
From b9f38b65417923624bf97a18daf1c2ede5e8651e Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sun, 15 Dec 2019 14:51:44 -0500
Subject: [PATCH] daemon: fix wayland detection when deciding to bypass
Xsession
At the moment if there's a session file with the same name in
both /usr/share/xsessions and /usr/share/wayland-sessions, GDM
will think the wayland is getting used when deciding whether or
not to bypass the /etc/gdm/Xsession script, even if wayland is
explicitly being ignored.
This commit fixes the check.
---
daemon/gdm-session.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index a8263ba11..ecb2b3cac 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -3145,96 +3145,96 @@ gdm_session_get_session_id (GdmSession *self)
return conversation->session_id;
}
const char *
gdm_session_get_conversation_session_id (GdmSession *self,
const char *service_name)
{
GdmSessionConversation *conversation;
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
conversation = find_conversation_by_name (self, service_name);
if (conversation == NULL) {
return NULL;
}
return conversation->session_id;
}
static char *
get_session_filename (GdmSession *self)
{
return g_strdup_printf ("%s.desktop", get_session_name (self));
}
#ifdef ENABLE_WAYLAND_SUPPORT
static gboolean
gdm_session_is_wayland_session (GdmSession *self)
{
- GKeyFile *key_file;
+ g_autoptr (GKeyFile) key_file = NULL;
gboolean is_wayland_session = FALSE;
- char *filename;
- char *full_path = NULL;
+ g_autofree char *filename = NULL;
+ g_autofree char *full_path = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
filename = get_session_filename (self);
- key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
+ if (!self->priv->ignore_wayland) {
+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
- if (key_file == NULL) {
- goto out;
- }
+ if (key_file == NULL) {
+ goto out;
+ }
- if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
- is_wayland_session = TRUE;
+ if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
+ is_wayland_session = TRUE;
+ }
}
- g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
out:
- g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free);
- g_free (filename);
+ g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
+
return is_wayland_session;
}
#endif
static void
update_session_type (GdmSession *self)
{
#ifdef ENABLE_WAYLAND_SUPPORT
gboolean is_wayland_session = FALSE;
- if (!self->priv->ignore_wayland)
- is_wayland_session = gdm_session_is_wayland_session (self);
+ is_wayland_session = gdm_session_is_wayland_session (self);
if (is_wayland_session) {
set_session_type (self, "wayland");
} else {
set_session_type (self, NULL);
}
#endif
}
gboolean
gdm_session_bypasses_xsession (GdmSession *self)
{
GError *error;
GKeyFile *key_file;
gboolean res;
gboolean bypasses_xsession = FALSE;
char *filename = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
#ifdef ENABLE_WAYLAND_SUPPORT
if (gdm_session_is_wayland_session (self)) {
bypasses_xsession = TRUE;
goto out;
}
#endif
filename = get_session_filename (self);
--
2.18.1

View File

@ -1,31 +0,0 @@
From 84eac5437175efc3804e8a6133c06484d6016b26 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 4 Jan 2019 16:40:07 -0500
Subject: [PATCH] data: disable wayland for legacy QXL VMs
There are a number of issues right now with the QXL driver that
prevent it from working well with wayland.
These days QXL is deprecated in favor of virtio anyway.
This commit forces Xorg fallback for QXL VMs.
---
data/61-gdm.rules.in | 3 +++
1 file changed, 3 insertions(+)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index 26cf9cf51..ec19aa447 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,5 +1,8 @@
# disable Wayland on Cirrus chipsets
ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
+# disable Wayland on legacy QXL virtual machines
+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", RUN+="@libexecdir@/gdm-disable-wayland"
+
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.17.1

View File

@ -1,4 +1,4 @@
From 21be64e1ba86bd57a4257a7526c9b4ee430bfdaa Mon Sep 17 00:00:00 2001 From 13a617e15cca421962be888b5607a9900bbfef51 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com> From: Ray Strode <rstrode@redhat.com>
Date: Mon, 11 Feb 2019 18:14:07 -0500 Date: Mon, 11 Feb 2019 18:14:07 -0500
Subject: [PATCH] data: disable wayland on server chips and dual gpu setups Subject: [PATCH] data: disable wayland on server chips and dual gpu setups
@ -12,10 +12,10 @@ This commit forces Xorg for those cases.
1 file changed, 18 insertions(+) 1 file changed, 18 insertions(+)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index ec19aa447..1c308d511 100644 index 26cf9cf51..e3631740d 100644
--- a/data/61-gdm.rules.in --- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in +++ b/data/61-gdm.rules.in
@@ -1,8 +1,26 @@ @@ -1,5 +1,23 @@
# disable Wayland on Cirrus chipsets # disable Wayland on Cirrus chipsets
ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
@ -33,9 +33,6 @@ index ec19aa447..1c308d511 100644
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland" +ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland" +ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
+ +
# disable Wayland on legacy QXL virtual machines
ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver # disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
+ +
@ -43,5 +40,5 @@ index ec19aa447..1c308d511 100644
+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland" +SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
+ +
-- --
2.18.1 2.21.0

View File

@ -0,0 +1,44 @@
From 7d9b41f1d82589999f8c89ed3bcc4eec6cee4978 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 6 Dec 2019 13:59:43 -0500
Subject: [PATCH] data: enable wayland on cirrus
cirrus in the 5.2 kernel was substantially rewritten and is more wayland
ready.
This commit reenables wayland on cirrus.
---
data/61-gdm.rules.in | 3 ---
1 file changed, 3 deletions(-)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index e3631740d..fc2e3315c 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,23 +1,20 @@
-# disable Wayland on Cirrus chipsets
-ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
-
# disable Wayland on Matrox chipsets
ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on aspeed chipsets
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on hybrid graphics setups for now
SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.21.0

View File

@ -0,0 +1,55 @@
From ab9510df0b5f7bc29662804991729c6d6ee38b70 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 12 Dec 2019 16:56:16 -0500
Subject: [PATCH] data: only disable wayland on passthrough virt setups
at the moment we disable wayland on all hybrid graphics setups,
but most hybrid graphics setups work fine.
The case we really care about is passthrough virt. in that case,
wayland is a bad idea because:
1) kernel crashes
2) mutter provides no way to disable one of the cards, and will
always use one as a secondary gpu
This commit forces xorg in passthrough setups so the user can use
an xorg.conf to turn one of the cards off.
---
data/61-gdm.rules.in | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index fc2e3315c..f971224cf 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,20 +1,25 @@
# disable Wayland on Matrox chipsets
ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on aspeed chipsets
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
-# disable Wayland on hybrid graphics setups for now
-SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
+# disable Wayland on passthrough graphics setups for now (assumes passthrough if
+# there is more than one card, and one of the cards is virt: cirrus, bochs, qxl)
+ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+ATTR{vendor}=="0x1234", ATTR{device}=="0x1111", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+
+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_VIRTUAL_GPU}=="1", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.21.0

View File

@ -0,0 +1,269 @@
From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sat, 14 Dec 2019 13:50:53 -0500
Subject: [PATCH] display: ask accountservice if there are users rather than
enumerate users
At the moment we ask accountsservice to give us the list of users just
to find out if there is a list of users.
That's rather inefficient and might be wrong for directory server users
that have never logged in before.
This commit changes gdm to ask accountsservice the question we really
want to know the answer to; whether or not there are users.
---
daemon/gdm-display.c | 55 ++++++++++++++++++--------------------------
1 file changed, 22 insertions(+), 33 deletions(-)
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 878be88da..875534272 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -57,62 +57,60 @@
struct GdmDisplayPrivate
{
char *id;
char *seat_id;
char *session_id;
char *session_class;
char *session_type;
char *remote_hostname;
int x11_display_number;
char *x11_display_name;
int status;
time_t creation_time;
GTimer *server_timer;
char *x11_cookie;
gsize x11_cookie_size;
GdmDisplayAccessFile *access_file;
guint finish_idle_id;
xcb_connection_t *xcb_connection;
int xcb_screen_number;
GDBusConnection *connection;
GdmDisplayAccessFile *user_access_file;
GdmDBusDisplay *display_skeleton;
GDBusObjectSkeleton *object_skeleton;
- GDBusProxy *accountsservice_proxy;
-
/* this spawns and controls the greeter session */
GdmLaunchEnvironment *launch_environment;
guint is_local : 1;
guint is_initial : 1;
guint allow_timed_login : 1;
guint have_existing_user_accounts : 1;
guint doing_initial_setup : 1;
};
enum {
PROP_0,
PROP_ID,
PROP_STATUS,
PROP_SEAT_ID,
PROP_SESSION_ID,
PROP_SESSION_CLASS,
PROP_SESSION_TYPE,
PROP_REMOTE_HOSTNAME,
PROP_X11_DISPLAY_NUMBER,
PROP_X11_DISPLAY_NAME,
PROP_X11_COOKIE,
PROP_X11_AUTHORITY_FILE,
PROP_IS_CONNECTED,
PROP_IS_LOCAL,
PROP_LAUNCH_ENVIRONMENT,
PROP_IS_INITIAL,
PROP_ALLOW_TIMED_LOGIN,
PROP_HAVE_EXISTING_USER_ACCOUNTS,
PROP_DOING_INITIAL_SETUP,
@@ -512,96 +510,88 @@ queue_finish (GdmDisplay *self)
if (self->priv->finish_idle_id == 0) {
self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self);
}
}
static void
_gdm_display_set_status (GdmDisplay *self,
int status)
{
if (status != self->priv->status) {
self->priv->status = status;
g_object_notify (G_OBJECT (self), "status");
}
}
static gboolean
gdm_display_real_prepare (GdmDisplay *self)
{
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
g_debug ("GdmDisplay: prepare display");
_gdm_display_set_status (self, GDM_DISPLAY_PREPARED);
return TRUE;
}
static void
look_for_existing_users_sync (GdmDisplay *self)
{
- GError *error = NULL;
- GVariant *call_result;
- GVariant *user_list;
-
- self->priv->accountsservice_proxy = g_dbus_proxy_new_sync (self->priv->connection,
- 0, NULL,
- "org.freedesktop.Accounts",
- "/org/freedesktop/Accounts",
- "org.freedesktop.Accounts",
- NULL,
- &error);
-
- if (!self->priv->accountsservice_proxy) {
- g_warning ("Failed to contact accountsservice: %s", error->message);
- goto out;
- }
-
- call_result = g_dbus_proxy_call_sync (self->priv->accountsservice_proxy,
- "ListCachedUsers",
- NULL,
- 0,
+ g_autoptr (GVariant) result = NULL;
+ g_autoptr (GVariant) result_child = NULL;
+ g_autoptr (GError) error = NULL;
+ gboolean has_no_users = FALSE;
+
+ result = g_dbus_connection_call_sync (self->priv->connection,
+ "org.freedesktop.Accounts",
+ "/org/freedesktop/Accounts",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"),
+ G_VARIANT_TYPE ("(v)"),
+ G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
- if (!call_result) {
- g_warning ("Failed to list cached users: %s", error->message);
- goto out;
+ if (result == NULL) {
+ g_warning ("Failed to contact accountsservice: %s", error->message);
+ return;
}
- g_variant_get (call_result, "(@ao)", &user_list);
- self->priv->have_existing_user_accounts = g_variant_n_children (user_list) > 0;
- g_variant_unref (user_list);
- g_variant_unref (call_result);
-out:
- g_clear_error (&error);
+ g_variant_get (result, "(v)", &result_child);
+ has_no_users = g_variant_get_boolean (result_child);
+ self->priv->have_existing_user_accounts = !has_no_users;
+
+ g_debug ("GdmDisplay: machine does %shave existing user accounts",
+ has_no_users? "not " : "");
}
gboolean
gdm_display_prepare (GdmDisplay *self)
{
gboolean ret;
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
g_debug ("GdmDisplay: Preparing display: %s", self->priv->id);
/* FIXME: we should probably do this in a more global place,
* asynchronously
*/
look_for_existing_users_sync (self);
self->priv->doing_initial_setup = wants_initial_setup (self);
g_object_ref (self);
ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self);
g_object_unref (self);
return ret;
}
gboolean
gdm_display_manage (GdmDisplay *self)
{
gboolean res;
@@ -1332,61 +1322,60 @@ gdm_display_init (GdmDisplay *self)
self->priv = GDM_DISPLAY_GET_PRIVATE (self);
self->priv->creation_time = time (NULL);
self->priv->server_timer = g_timer_new ();
}
static void
gdm_display_finalize (GObject *object)
{
GdmDisplay *self;
g_return_if_fail (object != NULL);
g_return_if_fail (GDM_IS_DISPLAY (object));
self = GDM_DISPLAY (object);
g_return_if_fail (self->priv != NULL);
g_debug ("GdmDisplay: Finalizing display: %s", self->priv->id);
g_free (self->priv->id);
g_free (self->priv->seat_id);
g_free (self->priv->session_class);
g_free (self->priv->remote_hostname);
g_free (self->priv->x11_display_name);
g_free (self->priv->x11_cookie);
g_clear_object (&self->priv->display_skeleton);
g_clear_object (&self->priv->object_skeleton);
g_clear_object (&self->priv->connection);
- g_clear_object (&self->priv->accountsservice_proxy);
if (self->priv->access_file != NULL) {
g_object_unref (self->priv->access_file);
}
if (self->priv->user_access_file != NULL) {
g_object_unref (self->priv->user_access_file);
}
if (self->priv->server_timer != NULL) {
g_timer_destroy (self->priv->server_timer);
}
G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
}
GDBusObjectSkeleton *
gdm_display_get_object_skeleton (GdmDisplay *self)
{
return self->priv->object_skeleton;
}
static void
on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment,
GdmDisplay *self)
{
char *session_id;
g_debug ("GdmDisplay: Greeter session opened");
session_id = gdm_launch_environment_get_session_id (launch_environment);
--
2.21.0

View File

@ -0,0 +1,343 @@
From bb58b5762272840a414f2bfe3ab59d733099a06c Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 20 Dec 2018 14:51:38 -0500
Subject: [PATCH 1/2] manager: allow multiple xdmcp logins for the same user
---
common/gdm-settings-keys.h | 1 +
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
data/gdm.schemas.in.in | 5 +++
3 files changed, 59 insertions(+), 18 deletions(-)
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index f0059b5cf..33676a851 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -28,37 +28,38 @@ G_BEGIN_DECLS
#define GDM_KEY_USER "daemon/User"
#define GDM_KEY_GROUP "daemon/Group"
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
#define GDM_KEY_DEBUG "debug/Enable"
#define GDM_KEY_INCLUDE "greeter/Include"
#define GDM_KEY_EXCLUDE "greeter/Exclude"
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin"
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
#define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter"
#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait"
#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost"
#define GDM_KEY_UDP_PORT "xdmcp/Port"
#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect"
#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect"
#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds"
#define GDM_KEY_WILLING "xdmcp/Willing"
+#define GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER "xdmcp/AllowMultipleSessionsPerUser"
#define GDM_KEY_MULTICAST "chooser/Multicast"
#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr"
G_END_DECLS
#endif /* _GDM_SETTINGS_KEYS_H */
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 056560b20..de7357ad5 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -594,93 +594,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
if (out_tty != NULL) {
*out_tty = get_tty_for_session_id (session_id, &error);
if (error != NULL) {
g_debug ("GdmManager: Error while retrieving tty for session: %s",
error->message);
g_clear_error (&error);
}
}
display = gdm_display_store_find (self->priv->display_store,
lookup_by_session_id,
(gpointer) session_id);
if (out_display != NULL) {
*out_display = display;
}
out:
g_free (session_id);
}
static gboolean
switch_to_compatible_user_session (GdmManager *manager,
GdmSession *session,
gboolean fail_if_already_switched)
{
gboolean res;
gboolean ret;
const char *username;
const char *seat_id;
- const char *ssid_to_activate;
+ const char *ssid_to_activate = NULL;
GdmSession *existing_session;
ret = FALSE;
username = gdm_session_get_username (session);
seat_id = gdm_session_get_display_seat_id (session);
- if (!fail_if_already_switched) {
- session = NULL;
- }
+ if (!fail_if_already_switched)
+ ssid_to_activate = gdm_session_get_session_id (session);
- existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
+ if (ssid_to_activate == NULL) {
+ if (!seat_id || !sd_seat_can_multi_session (seat_id)) {
+ g_debug ("GdmManager: unable to activate existing sessions from login screen unless on seat0");
+ goto out;
+ }
- if (existing_session != NULL) {
- ssid_to_activate = gdm_session_get_session_id (existing_session);
- if (seat_id != NULL) {
- res = activate_session_id (manager, seat_id, ssid_to_activate);
- if (! res) {
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
- goto out;
- }
+ if (!fail_if_already_switched) {
+ session = NULL;
}
- res = session_unlock (manager, ssid_to_activate);
- if (!res) {
- /* this isn't fatal */
- g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
+ existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
+
+ if (existing_session != NULL) {
+ ssid_to_activate = gdm_session_get_session_id (existing_session);
}
- } else {
+ }
+
+ if (ssid_to_activate == NULL) {
goto out;
}
+ if (seat_id != NULL) {
+ res = activate_session_id (manager, seat_id, ssid_to_activate);
+ if (! res) {
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
+ goto out;
+ }
+ }
+
+ res = session_unlock (manager, ssid_to_activate);
+ if (!res) {
+ /* this isn't fatal */
+ g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
+ }
+
ret = TRUE;
out:
return ret;
}
static GdmDisplay *
get_display_for_user_session (GdmSession *session)
{
return g_object_get_data (G_OBJECT (session), "gdm-display");
}
static GdmSession *
get_user_session_for_display (GdmDisplay *display)
{
if (display == NULL) {
return NULL;
}
return g_object_get_data (G_OBJECT (display), "gdm-user-session");
}
static gboolean
add_session_record (GdmManager *manager,
GdmSession *session,
GPid pid,
SessionRecord record)
{
const char *username;
char *display_name, *hostname, *display_device;
@@ -1088,92 +1101,114 @@ open_temporary_reauthentication_channel (GdmManager *self,
g_signal_connect (session,
"client-disconnected",
G_CALLBACK (on_reauthentication_client_disconnected),
self);
g_signal_connect (session,
"client-rejected",
G_CALLBACK (on_reauthentication_client_rejected),
self);
g_signal_connect (session,
"cancelled",
G_CALLBACK (on_reauthentication_cancelled),
self);
g_signal_connect (session,
"conversation-started",
G_CALLBACK (on_reauthentication_conversation_started),
self);
g_signal_connect (session,
"conversation-stopped",
G_CALLBACK (on_reauthentication_conversation_stopped),
self);
g_signal_connect (session,
"verification-complete",
G_CALLBACK (on_reauthentication_verification_complete),
self);
address = gdm_session_get_server_address (session);
return g_strdup (address);
}
+static gboolean
+remote_users_can_log_in_more_than_once (GdmManager *manager)
+{
+ gboolean enabled;
+
+ enabled = FALSE;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER, &enabled);
+
+ g_debug ("GdmDisplay: Remote users allowed to log in more than once: %s", enabled? "yes" : "no");
+
+ return enabled;
+}
+
static gboolean
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
GDBusMethodInvocation *invocation,
const char *username)
{
GdmManager *self = GDM_MANAGER (manager);
const char *sender;
GdmDisplay *display = NULL;
GdmSession *session;
GDBusConnection *connection;
char *seat_id = NULL;
char *session_id = NULL;
GPid pid = 0;
uid_t uid = (uid_t) -1;
gboolean is_login_screen = FALSE;
gboolean is_remote = FALSE;
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
sender = g_dbus_method_invocation_get_sender (invocation);
connection = g_dbus_method_invocation_get_connection (invocation);
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote);
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
_("No session available"));
return TRUE;
}
+ if (is_login_screen && is_remote && remote_users_can_log_in_more_than_once (self)) {
+ g_dbus_method_invocation_return_error_literal (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "Login screen creates new sessions for remote connections");
+ return TRUE;
+ }
+
if (is_login_screen) {
g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id);
session = find_session_for_user_on_seat (self,
username,
seat_id,
NULL);
} else {
g_debug ("GdmManager: looking for user session on display");
session = get_user_session_for_display (display);
}
if (session != NULL && gdm_session_is_running (session)) {
gdm_session_start_reauthentication (session, pid, uid);
g_hash_table_insert (self->priv->open_reauthentication_requests,
GINT_TO_POINTER (pid),
invocation);
} else if (is_login_screen) {
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Login screen only allowed to open reauthentication channels for running sessions");
return TRUE;
} else {
char *address;
address = open_temporary_reauthentication_channel (self,
seat_id,
session_id,
pid,
uid,
is_remote);
diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in
index 8ad203101..003f92c63 100644
--- a/data/gdm.schemas.in.in
+++ b/data/gdm.schemas.in.in
@@ -102,32 +102,37 @@
<schema>
<key>xdmcp/DisplaysPerHost</key>
<signature>i</signature>
<default>1</default>
</schema>
<schema>
<key>xdmcp/Port</key>
<signature>i</signature>
<default>177</default>
</schema>
<schema>
<key>xdmcp/HonorIndirect</key>
<signature>b</signature>
<default>true</default>
</schema>
<schema>
<key>xdmcp/MaxWaitIndirect</key>
<signature>i</signature>
<default>30</default>
</schema>
<schema>
<key>xdmcp/PingIntervalSeconds</key>
<signature>i</signature>
<default>0</default>
</schema>
<schema>
<key>xdmcp/Willing</key>
<signature>s</signature>
<default>@gdmconfdir@/Xwilling</default>
</schema>
+ <schema>
+ <key>xdmcp/AllowMultipleSessionsPerUser</key>
+ <signature>b</signature>
+ <default>false</default>
+ </schema>
</schemalist>
</gdmschemafile>
--
2.21.1

View File

@ -0,0 +1,87 @@
From ecd37ba6d56a49dd896613f68d1e1754633b9f0c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 6 Feb 2019 16:14:52 -0500
Subject: [PATCH 1/4] manager: don't kill timed login session immediately after
it starts
At the moment GDM is misidentifying timed login sessions as if
they are automatic login sessions. That leads to their displays
getting killed sometimes shortly after log in.
This commit corrects the check, so that timed login sessions aren't
treated as autologin sessions.
---
daemon/gdm-manager.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 2118c5834..b2d0578f5 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1841,61 +1841,62 @@ on_start_user_session (StartUserSessionOperation *operation)
NULL);
} else {
uid_t allowed_uid;
g_object_ref (display);
if (doing_initial_setup) {
g_debug ("GdmManager: closing down initial setup display");
gdm_display_stop_greeter_session (display);
gdm_display_unmanage (display);
gdm_display_finish (display);
/* We can't start the user session until the finished display
* starts to respawn (since starting an X server and bringing
* one down at the same time is a no go)
*/
g_assert (self->priv->initial_login_operation == NULL);
self->priv->initial_login_operation = operation;
starting_user_session_right_away = FALSE;
} else {
g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
}
/* The user session is going to follow the session worker
* into the new display. Untie it from this display and
* create a new session for a future user login. */
allowed_uid = gdm_session_get_allowed_user (operation->session);
g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL);
create_user_session_for_display (operation->manager, display, allowed_uid);
- if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) {
+ if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) &&
+ !gdm_session_client_is_connected (operation->session)) {
gboolean was_initial = FALSE;
g_object_get (G_OBJECT (display), "is-initial", &was_initial, NULL);
/* remove the unused prepared greeter display since we're not going
* to have a greeter */
gdm_display_store_remove (self->priv->display_store, display);
g_object_unref (display);
should_be_initial = was_initial;
}
/* Give the user session a new display object for bookkeeping purposes */
create_display_for_user_session (operation->manager,
operation->session,
session_id,
should_be_initial);
}
if (starting_user_session_right_away) {
start_user_session (operation->manager, operation);
}
out:
return G_SOURCE_REMOVE;
}
static void
queue_start_user_session (GdmManager *manager,
GdmSession *session,
--
2.21.0

View File

@ -0,0 +1,165 @@
From 84b823187c8e0b23274cd1a93f4e47a2c585c75b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 5 Feb 2020 15:20:48 -0500
Subject: [PATCH 2/2] gdm-x-session: run session bus on non-seat0 seats
GNOME doesn't deal very well with multiple sessions
running on a multiple seats at the moment.
Until that's fixed, ensure sessions run on auxillary
seats get their own session bus.
---
daemon/gdm-session.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index a8263ba11..55637b378 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -2846,130 +2846,139 @@ on_start_program_cb (GdmDBusWorker *worker,
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
self = conversation->session;
service_name = conversation->service_name;
if (worked) {
self->priv->session_pid = pid;
self->priv->session_conversation = conversation;
g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid);
g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, pid);
} else {
gdm_session_stop_conversation (self, service_name);
g_debug ("GdmSession: Emitting 'session-start-failed' signal");
g_signal_emit (self, signals[SESSION_START_FAILED], 0, service_name, error->message);
}
}
void
gdm_session_start_session (GdmSession *self,
const char *service_name)
{
GdmSessionConversation *conversation;
GdmSessionDisplayMode display_mode;
gboolean is_x11 = TRUE;
gboolean run_launcher = FALSE;
gboolean allow_remote_connections = FALSE;
+ gboolean run_separate_bus = FALSE;
char *command;
char *program;
g_return_if_fail (GDM_IS_SESSION (self));
g_return_if_fail (self->priv->session_conversation == NULL);
conversation = find_conversation_by_name (self, service_name);
if (conversation == NULL) {
g_warning ("GdmSession: Tried to start session of "
"nonexistent conversation %s", service_name);
return;
}
stop_all_other_conversations (self, conversation, FALSE);
display_mode = gdm_session_get_display_mode (self);
#ifdef ENABLE_WAYLAND_SUPPORT
is_x11 = g_strcmp0 (self->priv->session_type, "wayland") != 0;
#endif
if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED ||
display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) {
run_launcher = TRUE;
}
+ if (g_strcmp0 (self->priv->display_seat_id, "seat0") != 0 && !run_launcher) {
+ run_separate_bus = TRUE;
+ }
+
if (self->priv->selected_program == NULL) {
gboolean run_xsession_script;
command = get_session_command (self);
run_xsession_script = !gdm_session_bypasses_xsession (self);
if (self->priv->display_is_local) {
gboolean disallow_tcp = TRUE;
gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp);
allow_remote_connections = !disallow_tcp;
} else {
allow_remote_connections = TRUE;
}
if (run_launcher) {
if (is_x11) {
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s %s\"%s\"",
run_xsession_script? "--run-script " : "",
allow_remote_connections? "--allow-remote-connections " : "",
command);
} else {
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"",
command);
}
} else if (run_xsession_script) {
- program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
+ if (run_separate_bus) {
+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command);
+ } else {
+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
+ }
} else {
program = g_strdup (command);
}
g_free (command);
} else {
if (run_launcher) {
if (is_x11) {
- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"",
- self->priv->selected_program);
+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"",
+ self->priv->selected_program);
} else {
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"",
self->priv->selected_program);
}
} else {
- if (g_strcmp0 (self->priv->display_seat_id, "seat0") != 0) {
+ if (run_separate_bus) {
program = g_strdup_printf ("dbus-run-session -- %s",
self->priv->selected_program);
} else {
program = g_strdup (self->priv->selected_program);
}
}
}
set_up_session_environment (self);
send_environment (self, conversation);
gdm_dbus_worker_call_start_program (conversation->worker_proxy,
program,
conversation->worker_cancellable,
(GAsyncReadyCallback) on_start_program_cb,
conversation);
g_free (program);
}
static void
stop_all_conversations (GdmSession *self)
{
stop_all_other_conversations (self, NULL, TRUE);
}
static void
do_reset (GdmSession *self)
{
stop_all_conversations (self);
--
2.21.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
From 7b83c1dc9645cabadfeb253d7eca427f6a26d10f Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
Date: Thu, 31 Jan 2019 17:51:52 +0000
Subject: [PATCH 3/4] 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 f23a83c5e..a8263ba11 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -1401,130 +1401,205 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier *u
static gboolean
gdm_session_handle_client_answer_query (GdmDBusUserVerifier *user_verifier_interface,
GDBusMethodInvocation *invocation,
const char *service_name,
const char *answer,
GdmSession *self)
{
gdm_dbus_user_verifier_complete_answer_query (user_verifier_interface,
invocation);
gdm_session_answer_query (self, service_name, answer);
return TRUE;
}
static gboolean
gdm_session_handle_client_cancel (GdmDBusUserVerifier *user_verifier_interface,
GDBusMethodInvocation *invocation,
GdmSession *self)
{
gdm_dbus_user_verifier_complete_cancel (user_verifier_interface,
invocation);
gdm_session_cancel (self);
return TRUE;
}
static gboolean
gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
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);
}
gdm_session_select_session (self, session);
return TRUE;
}
static gboolean
gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
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);
}
g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self);
gdm_session_select_user (self, username);
return TRUE;
}
static gboolean
gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *service_name,
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,
invocation);
}
g_signal_emit (G_OBJECT (self),
signals [CLIENT_READY_FOR_SESSION_TO_START],
0,
service_name,
client_is_ready);
return TRUE;
}
static gboolean
gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface,
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,
invocation,
self->priv->timed_login_username != NULL,
self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
self->priv->timed_login_delay);
if (self->priv->timed_login_username != NULL) {
gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
self->priv->timed_login_username,
self->priv->timed_login_delay);
}
}
return TRUE;
}
static gboolean
gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
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);
}
g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)",
username,
gdm_session_get_session_id (self),
self);
gdm_session_setup_for_user (self, "gdm-autologin", username);
return TRUE;
}
static void
export_user_verifier_interface (GdmSession *self,
GDBusConnection *connection)
{
GdmDBusUserVerifier *user_verifier_interface;
user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ());
g_object_set_data (G_OBJECT (connection), "gdm-session", self);
g_signal_connect (user_verifier_interface,
"handle-enable-extensions",
G_CALLBACK (gdm_session_handle_client_enable_extensions),
connection);
g_signal_connect (user_verifier_interface,
"handle-begin-verification",
--
2.21.0

View File

@ -0,0 +1,105 @@
From 15a19ac7856c539aa9cfbf76997d18b0275aae35 Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
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

View File

@ -10,40 +10,54 @@
Name: gdm Name: gdm
Epoch: 1 Epoch: 1
Version: 3.28.3 Version: 3.28.3
Release: 22%{?dist} Release: 29%{?dist}
Summary: The GNOME Display Manager Summary: The GNOME Display Manager
License: GPLv2+ License: GPLv2+
URL: https://wiki.gnome.org/Projects/GDM URL: https://wiki.gnome.org/Projects/GDM
Source0: http://download.gnome.org/sources/gdm/3.28/gdm-%{version}.tar.xz Source0: http://download.gnome.org/sources/gdm/3.28/gdm-%{version}.tar.xz
Source1: org.gnome.login-screen.gschema.override Source1: org.gnome.login-screen.gschema.override
Patch0: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch Patch00001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch
Patch11: 0001-utils-add-new-gdm-disable-wayland-binary.patch Patch10001: 0001-utils-add-new-gdm-disable-wayland-binary.patch
Patch31: 0001-display-access-file-drop-unused-function.patch Patch20001: 0001-display-access-file-drop-unused-function.patch
Patch41: 0001-data-disable-wayland-for-proprietary-nvidia-machines.patch Patch30001: 0001-data-disable-wayland-for-proprietary-nvidia-machines.patch
Patch42: 0001-data-disable-wayland-for-legacy-QXL-VMs.patch Patch30002: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch
Patch43: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch Patch30003: 0001-data-enable-wayland-on-cirrus.patch
Patch30004: 0001-data-only-disable-wayland-on-passthrough-virt-setups.patch
Patch51: 0001-local-display-factory-pause-for-a-few-seconds-before.patch Patch40001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch
Patch61: 0001-manager-ensure-is-initial-is-transfered-to-autologin.patch Patch50001: 0001-manager-ensure-is-initial-is-transfered-to-autologin.patch
Patch71: 0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch Patch60001: 0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch
Patch81: 0001-worker-don-t-load-user-settings-for-program-sessions.patch Patch70001: 0001-worker-don-t-load-user-settings-for-program-sessions.patch
Patch82: 0002-session-support-new-accountsservice-Session-and-Sess.patch Patch70002: 0002-session-support-new-accountsservice-Session-and-Sess.patch
Patch83: 0003-daemon-save-os-release-in-accountsservice.patch Patch70003: 0003-daemon-save-os-release-in-accountsservice.patch
Patch84: 0004-daemon-handle-upgrades-from-RHEL-7.patch Patch70004: 0004-daemon-handle-upgrades-from-RHEL-7.patch
Patch91: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch Patch80001: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch
Patch92: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch Patch80002: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch
Patch93: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch Patch80003: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch
Patch94: 0004-data-reap-gdm-sessions-on-shutdown.patch Patch80004: 0004-data-reap-gdm-sessions-on-shutdown.patch
Patch9999: system-dconf.patch # CVE-2019-3825
Patch90001: 0001-manager-don-t-kill-timed-login-session-immediately-a.patch
Patch90002: 0002-manager-session-Add-some-debugging-around-starting-r.patch
Patch90003: 0003-session-Don-t-allow-greeter-operations-on-an-running.patch
Patch90004: 0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch
Patch100001: 0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch
Patch100002: 0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch
Patch110001: 0001-display-ask-accountservice-if-there-are-users-rather.patch
Patch120001: 0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch
Patch999999: system-dconf.patch
BuildRequires: pam-devel >= 0:%{pam_version} BuildRequires: pam-devel >= 0:%{pam_version}
BuildRequires: desktop-file-utils >= %{desktop_file_utils_version} BuildRequires: desktop-file-utils >= %{desktop_file_utils_version}
@ -343,6 +357,38 @@ fi
%{_libdir}/pkgconfig/gdm-pam-extensions.pc %{_libdir}/pkgconfig/gdm-pam-extensions.pc
%changelog %changelog
* Wed Feb 05 2020 Ray Strode <rstrode@redhat.com> - 3.28.3-29
- Make GNOME work slightly better in the multiple logins case.
Related: #1710882
* Sun Dec 15 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-28
- Correct wayland session detection logic when deciding
whether or not to run Xsession script
Resolves: #1728330
* Sun Dec 15 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-27
- Don't run initial-setup for machines enrolled in IPA setup.
Resolves: #1750516
* Fri Dec 13 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-26
- Forward port RHEL 7 patch to allow multiple logins for the
same user with XDMCP connections.
Resolves: #1710882
* Thu Dec 12 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-25
- Reenable wayland on hybrid setups (except virt pass through)
Resolves: #1749960
- Reenable wayland on qxl
Resolves: #1744452
* Fri Dec 06 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-24
- Reenable wayland on cirrus
Resolves: #1744527
* Thu Nov 21 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-23
- Correct timedlogin based screenlock bypass
Resolves: #1672829
* Mon Jun 24 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-22 * Mon Jun 24 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-22
- Ensure user session is killed with its worker and that all - Ensure user session is killed with its worker and that all
user sessions are cleaned up on shutdown user sessions are cleaned up on shutdown