From 58c887ef1d3f349e44825835510d05db98e49842 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 22 2021 10:19:20 +0000 Subject: import gdm-40.0-16.el8 --- diff --git a/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch b/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch new file mode 100644 index 0000000..080052f --- /dev/null +++ b/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch @@ -0,0 +1,325 @@ +From d8fd8d4d6ff6a119f6bd27eb07316384c4776d12 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 15 Sep 2021 11:23:17 -0400 +Subject: [PATCH] local-display-factory: Don't try to respawn displays on + shutdown + +At the moment in the shutdown path we may try to respawn displays +that just got killed. + +The respawning happens when things are half torn down leading to +crashes. + +This commit makes sure we turn off the respawn logic in the shutdown +path. +--- + daemon/gdm-local-display-factory.c | 11 ++++++++++- + daemon/gdm-manager.c | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 11dcda2c..a0884893 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -46,60 +46,62 @@ + #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" + #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" + + #define MAX_DISPLAY_FAILURES 5 + #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ + #define SEAT0_GRAPHICS_CHECK_TIMEOUT 10 /* seconds */ + + struct _GdmLocalDisplayFactory + { + GdmDisplayFactory parent; + + GdmDBusLocalDisplayFactory *skeleton; + GDBusConnection *connection; + GHashTable *used_display_numbers; + + /* FIXME: this needs to be per seat? */ + guint num_failures; + + guint seat_new_id; + guint seat_removed_id; + guint seat_properties_changed_id; + + gboolean seat0_graphics_check_timed_out; + guint seat0_graphics_check_timeout_id; + + #if defined(ENABLE_USER_DISPLAY_SERVER) + unsigned int active_vt; + guint active_vt_watch_id; + guint wait_to_finish_timeout_id; + #endif ++ ++ gboolean is_started; + }; + + enum { + PROP_0, + }; + + static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); + static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); + static void gdm_local_display_factory_finalize (GObject *object); + + static void ensure_display_for_seat (GdmLocalDisplayFactory *factory, + const char *seat_id); + + static void on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory); + + static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); + static gpointer local_display_factory_object = NULL; + static gboolean lookup_by_session_id (const char *id, + GdmDisplay *display, + gpointer user_data); + + G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) + + GQuark + gdm_local_display_factory_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { +@@ -478,60 +480,64 @@ on_session_registered_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) + { + GdmDisplay *display = GDM_DISPLAY (gobject); + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); + gboolean registered; + + g_object_get (display, "session-registered", ®istered, NULL); + + if (!registered) + return; + + g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); + + finish_waiting_displays_on_seat (factory, "seat0"); + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory) + { + int status; + int num; + char *seat_id = NULL; + char *session_type = NULL; + char *session_class = NULL; + gboolean is_initial = TRUE; + gboolean is_local = TRUE; + ++ ++ if (!factory->is_started) ++ return; ++ + num = -1; + gdm_display_get_x11_display_number (display, &num, NULL); + + g_object_get (display, + "seat-id", &seat_id, + "is-initial", &is_initial, + "is-local", &is_local, + "session-type", &session_type, + "session-class", &session_class, + NULL); + + status = gdm_display_get_status (display); + + g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); + switch (status) { + case GDM_DISPLAY_FINISHED: + /* remove the display number from factory->used_display_numbers + so that it may be reused */ + if (num != -1) { + g_hash_table_remove (factory->used_display_numbers, GUINT_TO_POINTER (num)); + } + gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); + + /* if this is a local display, do a full resync. Only + * seats without displays will get created anyway. This + * ensures we get a new login screen when the user logs out, + * if there isn't one. + */ + if (is_local && g_strcmp0 (session_class, "greeter") != 0) { + /* reset num failures */ +@@ -1250,99 +1256,102 @@ on_display_added (GdmDisplayStore *display_store, + + display = gdm_display_store_lookup (display_store, id); + + if (display != NULL) { + g_signal_connect_object (display, "notify::status", + G_CALLBACK (on_display_status_changed), + factory, + 0); + + g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); + } + } + + static void + on_display_removed (GdmDisplayStore *display_store, + GdmDisplay *display, + GdmLocalDisplayFactory *factory) + { + g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory); + g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); + } + + static gboolean + gdm_local_display_factory_start (GdmDisplayFactory *base_factory) + { + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); + GdmDisplayStore *store; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + ++ factory->is_started = TRUE; ++ + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_signal_connect_object (G_OBJECT (store), + "display-added", + G_CALLBACK (on_display_added), + factory, + 0); + + g_signal_connect_object (G_OBJECT (store), + "display-removed", + G_CALLBACK (on_display_removed), + factory, + 0); + + gdm_local_display_factory_start_monitor (factory); + return gdm_local_display_factory_sync_seats (factory); + } + + static gboolean + gdm_local_display_factory_stop (GdmDisplayFactory *base_factory) + { + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); + GdmDisplayStore *store; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + + gdm_local_display_factory_stop_monitor (factory); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_signal_handlers_disconnect_by_func (G_OBJECT (store), + G_CALLBACK (on_display_added), + factory); + g_signal_handlers_disconnect_by_func (G_OBJECT (store), + G_CALLBACK (on_display_removed), + factory); +- + g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); + ++ factory->is_started = FALSE; ++ + return TRUE; + } + + static void + gdm_local_display_factory_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) + { + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_local_display_factory_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) + { + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static gboolean +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index b3d0a2b5..4b62b8b1 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -2774,60 +2774,62 @@ unexport_display (const char *id, + GdmDisplay *display, + GdmManager *manager) + { + if (!g_dbus_connection_is_closed (manager->priv->connection)) + g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); + } + + static void + finish_display (const char *id, + GdmDisplay *display, + GdmManager *manager) + { + gdm_display_stop_greeter_session (display); + if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) + gdm_display_unmanage (display); + gdm_display_finish (display); + } + + static void + gdm_manager_dispose (GObject *object) + { + GdmManager *manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_MANAGER (object)); + + manager = GDM_MANAGER (object); + + g_return_if_fail (manager->priv != NULL); + ++ gdm_manager_stop (manager); ++ + g_clear_weak_pointer (&manager->priv->automatic_login_display); + + #ifdef HAVE_LIBXDMCP + g_clear_object (&manager->priv->xdmcp_factory); + #endif + g_clear_object (&manager->priv->local_factory); + g_clear_pointer (&manager->priv->open_reauthentication_requests, + g_hash_table_unref); + g_clear_pointer (&manager->priv->transient_sessions, + g_hash_table_unref); + + g_list_foreach (manager->priv->user_sessions, + (GFunc) gdm_session_close, + NULL); + g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); + manager->priv->user_sessions = NULL; + + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_added), + manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_removed), + manager); + + if (!g_dbus_connection_is_closed (manager->priv->connection)) { + gdm_display_store_foreach (manager->priv->display_store, + (GdmDisplayStoreFunc)unexport_display, + manager); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); + } +-- +2.31.1 + diff --git a/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch b/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch new file mode 100644 index 0000000..8e5eb3e --- /dev/null +++ b/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch @@ -0,0 +1,122 @@ +From e3a7ca44c0153ffa895786eabb020810b138eea2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 14 Sep 2021 11:00:33 -0400 +Subject: [PATCH 3/3] xdmcp-display-factory: Set supported session types for + XDMCP displays + +The lower levels of GDM now expect the session types supported by a +display to be specified up front. + +This commit makes sure XDMCP displays do that. +--- + daemon/gdm-xdmcp-display-factory.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c +index ce8f026e1..558458f1c 100644 +--- a/daemon/gdm-xdmcp-display-factory.c ++++ b/daemon/gdm-xdmcp-display-factory.c +@@ -2104,94 +2104,100 @@ on_display_status_changed (GdmDisplay *display, + break; + case GDM_DISPLAY_MANAGED: + if (session != NULL) { + g_signal_connect_object (G_OBJECT (session), + "client-disconnected", + G_CALLBACK (on_client_disconnected), + display, G_CONNECT_SWAPPED); + g_signal_connect_object (G_OBJECT (session), + "disconnected", + G_CALLBACK (on_client_disconnected), + display, G_CONNECT_SWAPPED); + } + break; + default: + g_assert_not_reached (); + break; + } + + g_clear_object (&launch_environment); + } + + static GdmDisplay * + gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, + const char *hostname, + GdmAddress *address, + int displaynum) + { + GdmDisplay *display; + GdmDisplayStore *store; + gboolean use_chooser; ++ const char *session_types[] = { "x11", NULL }; + + g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d", + hostname ? hostname : "(null)", displaynum); + + use_chooser = FALSE; + if (factory->honor_indirect) { + IndirectClient *ic; + + ic = indirect_client_lookup (factory, address); + + /* This was an indirect thingie and nothing was yet chosen, + * use a chooser */ + if (ic != NULL && ic->chosen_address == NULL) { + use_chooser = TRUE; + } + } + + if (use_chooser) { + display = gdm_xdmcp_chooser_display_new (hostname, + displaynum, + address, + get_next_session_serial (factory)); + g_signal_connect (display, "hostname-selected", G_CALLBACK (on_hostname_selected), factory); + } else { + display = gdm_xdmcp_display_new (hostname, + displaynum, + address, + get_next_session_serial (factory)); + } + + if (display == NULL) { + goto out; + } + ++ g_object_set (G_OBJECT (display), ++ "session-type", session_types[0], ++ "supported-session-types", session_types, ++ NULL); ++ + if (! gdm_display_prepare (display)) { + gdm_display_unmanage (display); + g_object_unref (display); + display = NULL; + goto out; + } + + g_signal_connect_after (display, + "notify::status", + G_CALLBACK (on_display_status_changed), + factory); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + gdm_display_store_add (store, display); + + factory->num_pending_sessions++; + out: + + return display; + } + + static void + gdm_xdmcp_send_accept (GdmXdmcpDisplayFactory *factory, + GdmAddress *address, + CARD32 session_id, + ARRAY8Ptr authentication_name, + ARRAY8Ptr authentication_data, + ARRAY8Ptr authorization_name, + ARRAY8Ptr authorization_data) + { +-- +2.31.1 + diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index 67e7819..bdecd3c 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -12,7 +12,7 @@ Name: gdm Epoch: 1 Version: 40.0 -Release: 13%{?dist} +Release: 16%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -23,6 +23,7 @@ Source1: org.gnome.login-screen.gschema.override # Lets customers using vendor nvidia driver pick wayland sessions from the login screen Patch10001: 0001-local-display-factory-Provide-more-flexibility-for-c.patch Patch10002: 0002-libgdm-Sort-session-list.patch +Patch10003: 0003-xdmcp-display-factory-Set-supported-session-types-fo.patch # Race fix Patch40001: 0001-display-Handle-failure-before-display-registration.patch @@ -38,6 +39,9 @@ Patch60003: 0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch # Upstream change that's moderately risky so revert it Patch70001: 0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch +# Crash fix +Patch80001: 0001-local-display-factory-Don-t-try-to-respawn-displays-.patch + # Non-upstreamable workarounds Patch66610001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch Patch66620001: 0001-data-reap-gdm-sessions-on-shutdown.patch @@ -360,10 +364,16 @@ fi %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog -* Wed Sep 01 2021 Ray Strode - 40.0-13 +* Wed Sep 15 2021 Ray Strode - 40.0-16 +- Fix XDMCP + Resolves: #2005011 +- Fix crash at shutdown + Related: #2005011 + +* Wed Sep 01 2021 Ray Strode - 40.0-14 - Disable Wayland on HyperV - Fix Xorg fallback - Related: #1998989 + Related: #2000904 * Thu Aug 19 2021 Ray Strode - 40.0-12 - Redisable on server chips since rebase