From 2c47cc5b1869c5e59f509892d748ca6f676131aa Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 18 2021 06:47:54 +0000 Subject: import gdm-3.28.3-39.el8 --- diff --git a/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch b/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch new file mode 100644 index 0000000..ffd5b94 --- /dev/null +++ b/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch @@ -0,0 +1,140 @@ +From e339ad74ca408c665a62bb4bd98dd1ef6caedd20 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 27 Oct 2020 15:14:27 +0100 +Subject: [PATCH] display: Exit with failure if loading existing users fails + +Given not having users may make GDM to launch initial setup, that +allows to create new users (potentially with sudo capabilities), it's +better to make look_for_existing_users() to return its status and only +if it didn't fail continue the gdm execution. + +GHSL-2020-202 +CVE-2020-16125 + +Fixes #642 +--- + daemon/gdm-display.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 929fa13bd..1b60eb621 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -436,106 +436,110 @@ finish_idle (GdmDisplay *self) + static void + 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 ++static gboolean + look_for_existing_users_sync (GdmDisplay *self) + { + 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 (result == NULL) { +- g_warning ("Failed to contact accountsservice: %s", error->message); +- return; ++ g_critical ("Failed to contact accountsservice: %s", error->message); ++ goto out; + } + + 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 " : ""); ++out: ++ return result != NULL; + } + + 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); ++ if (!look_for_existing_users_sync (self)) { ++ exit (EXIT_FAILURE); ++ } + + 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; + + g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); + + g_debug ("GdmDisplay: Managing display: %s", self->priv->id); + + /* If not explicitly prepared, do it now */ + if (self->priv->status == GDM_DISPLAY_UNMANAGED) { + res = gdm_display_prepare (self); + if (! res) { + return FALSE; + } + } + + if (g_strcmp0 (self->priv->session_class, "greeter") == 0) { + if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) { + GDM_DISPLAY_GET_CLASS (self)->manage (self); +-- +2.28.0 + diff --git a/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch b/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch new file mode 100644 index 0000000..9a4c4df --- /dev/null +++ b/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch @@ -0,0 +1,683 @@ +From 3864af1ea06d2125c1b1f5afa6fc12caa833980a Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 10 Dec 2020 15:14:20 -0500 +Subject: [PATCH] session-worker: Don't switch back VTs until session is fully + exited + +There's a race condition on shutdown where the session worker is +switching VTs back to the initial VT at the same time as the session +exit is being processed. + +This means that manager may try to start a login screen (because of +the VT switch) when autologin is enabled when there shouldn't be a +login screen. + +This commit makes sure both the PostSession script, and session-exited +signal emission are complete before initiating the VT switch back +to the initial VT. + +https://gitlab.gnome.org/GNOME/gdm/-/issues/660 +--- + daemon/Makefile.am | 12 +++++ + daemon/gdm-session-worker.c | 93 +++++++++++++++++++++++++++------ + daemon/org.freedesktop.DBus.xml | 12 +++++ + 3 files changed, 101 insertions(+), 16 deletions(-) + create mode 100644 daemon/org.freedesktop.DBus.xml + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 86a8ee32f..b323f6455 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -7,83 +7,92 @@ AM_CPPFLAGS = \ + -I$(top_srcdir)/pam-extensions \ + -I$(top_builddir)/common \ + -DBINDIR=\"$(bindir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DDMCONFDIR=\"$(dmconfdir)\" \ + -DGDMCONFDIR=\"$(gdmconfdir)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DLOGDIR=\"$(logdir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ + -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ + -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ + -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ + -DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \ + $(DISABLE_DEPRECATED_CFLAGS) \ + $(DAEMON_CFLAGS) \ + $(XLIB_CFLAGS) \ + $(WARN_CFLAGS) \ + $(DEBUG_CFLAGS) \ + $(SYSTEMD_CFLAGS) \ + $(JOURNALD_CFLAGS) \ + $(LIBSELINUX_CFLAGS) \ + -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ + $(NULL) + + BUILT_SOURCES = \ ++ gdm-dbus-glue.h \ + gdm-display-glue.h \ + gdm-manager-glue.h \ + gdm-local-display-glue.h \ + gdm-local-display-factory-glue.h \ + gdm-session-glue.h \ + gdm-session-worker-glue.h \ + gdm-session-enum-types.h \ + gdm-session-worker-enum-types.h \ + com.redhat.AccountsServiceUser.System.h \ + $(NULL) + + gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h + $(AM_V_GEN) glib-mkenums --template $^ > $@ + + gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h + $(AM_V_GEN) glib-mkenums --template $^ > $@ + + gdm-session-worker-enum-types.h: gdm-session-worker-enum-types.h.in gdm-session-worker.h + $(AM_V_GEN) glib-mkenums --template $^ > $@ + + gdm-session-worker-enum-types.c: gdm-session-worker-enum-types.c.in gdm-session-worker.h + $(AM_V_GEN) glib-mkenums --template $^ > $@ + ++gdm-dbus-glue.c gdm-dbus-glue.h: org.freedesktop.DBus.xml Makefile.am ++ $(AM_V_GEN)gdbus-codegen \ ++ --c-namespace=GdmDBus \ ++ --interface-prefix=org.freedesktop.DBus \ ++ --generate-c-code=gdm-dbus-glue \ ++ --c-generate-autocleanup=all \ ++ $(srcdir)/org.freedesktop.DBus.xml ++ + gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am + $(AM_V_GEN)gdbus-codegen \ + --c-namespace=GdmDBus \ + --interface-prefix=org.gnome.DisplayManager \ + --generate-c-code=gdm-display-glue \ + $(srcdir)/gdm-display.xml + + gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am + $(AM_V_GEN)gdbus-codegen \ + --c-namespace=GdmDBus \ + --interface-prefix=org.gnome.DisplayManager \ + --generate-c-code=gdm-local-display-glue \ + $(srcdir)/gdm-local-display.xml + + gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am + $(AM_V_GEN)gdbus-codegen \ + --c-namespace=GdmDBus \ + --interface-prefix=org.gnome.DisplayManager \ + --generate-c-code=gdm-local-display-factory-glue \ + $(srcdir)/gdm-local-display-factory.xml + + gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am + $(AM_V_GEN)gdbus-codegen \ + --c-namespace=GdmDBus \ + --interface-prefix=org.gnome.DisplayManager \ + --generate-c-code=gdm-manager-glue \ + $(srcdir)/gdm-manager.xml + + gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am + $(AM_V_GEN)gdbus-codegen \ +@@ -130,60 +139,62 @@ libexec_PROGRAMS = \ + gdm-wayland-session \ + gdm-x-session \ + $(NULL) + + gdm_session_worker_SOURCES = \ + session-worker-main.c \ + com.redhat.AccountsServiceUser.System.h \ + com.redhat.AccountsServiceUser.System.c \ + gdm-session.c \ + gdm-session.h \ + gdm-session-settings.h \ + gdm-session-settings.c \ + gdm-session-auditor.h \ + gdm-session-auditor.c \ + gdm-session-record.c \ + gdm-session-record.h \ + gdm-session-worker.h \ + gdm-session-worker.c \ + gdm-session-worker-job.c \ + gdm-session-worker-common.c \ + gdm-session-worker-common.h \ + gdm-dbus-util.c \ + gdm-dbus-util.h \ + $(NULL) + + if SUPPORTS_PAM_EXTENSIONS + gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h + endif + + nodist_gdm_session_worker_SOURCES = \ ++ gdm-dbus-glue.h \ ++ gdm-dbus-glue.c \ + gdm-session-glue.h \ + gdm-session-glue.c \ + gdm-session-worker-glue.c \ + gdm-session-worker-glue.h \ + gdm-session-enum-types.c \ + gdm-session-worker-enum-types.c \ + gdm-session-enum-types.h \ + $(NULL) + + gdm_wayland_session_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(GTK_LIBS) \ + $(COMMON_LIBS) \ + $(SYSTEMD_LIBS) \ + $(NULL) + + gdm_wayland_session_SOURCES = \ + gdm-manager-glue.h \ + gdm-manager-glue.c \ + gdm-wayland-session.c \ + $(NULL) + + gdm_x_session_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(GTK_LIBS) \ + $(COMMON_LIBS) \ + $(SYSTEMD_LIBS) \ + $(XLIB_LIBS) \ + $(NULL) + +@@ -271,50 +282,51 @@ nodist_gdm_SOURCES = \ + + XDMCP_SOURCES = \ + gdm-xdmcp-display-factory.c \ + gdm-xdmcp-display-factory.h \ + gdm-xdmcp-display.c \ + gdm-xdmcp-display.h \ + gdm-xdmcp-chooser-display.c \ + gdm-xdmcp-chooser-display.h \ + $(NULL) + + if XDMCP_SUPPORT + gdm_SOURCES += $(XDMCP_SOURCES) + endif + + EXTRA_gdm_SOURCES = \ + $(XDMCP_SOURCES) \ + $(NULL) + + gdm_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(XLIB_LIBS) \ + $(DAEMON_LIBS) \ + $(XDMCP_LIBS) \ + $(LIBWRAP_LIBS) \ + $(SYSTEMD_LIBS) \ + $(JOURNALD_LIBS) \ + $(EXTRA_DAEMON_LIBS) \ + $(NULL) + + CLEANFILES = \ ++ gdm-dbus-glue.c \ + gdm-display-glue.c \ + gdm-local-display-factory-glue.c \ + gdm-manager-glue.c \ + gdm-session-glue.c \ + gdm-session-worker-glue.c \ + gdm-session-enum-types.c \ + gdm-local-display-glue.c \ + $(BUILT_SOURCES) \ + $(NULL) + + EXTRA_DIST = \ + gdm-manager.xml \ + gdm-session-worker.xml \ + gdm-session.xml \ + gdm-display.xml \ + gdm-local-display.xml \ + gdm-local-display-factory.xml \ + gdm-session-enum-types.c.in \ + gdm-session-enum-types.h.in \ + $(NULL) +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index 42c415837..c1b2c1765 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -39,60 +39,61 @@ + + #ifdef HAVE_LOGINCAP + #include + #endif + + #include + #include + #include + #include + #include + + #include + + #include + + #ifdef ENABLE_SYSTEMD_JOURNAL + #include + #endif + + #ifdef HAVE_SELINUX + #include + #endif /* HAVE_SELINUX */ + + #include "gdm-common.h" + #include "gdm-log.h" + + #ifdef SUPPORTS_PAM_EXTENSIONS + #include "gdm-pam-extensions.h" + #endif + ++#include "gdm-dbus-glue.h" + #include "gdm-session-worker.h" + #include "gdm-session-glue.h" + #include "gdm-session.h" + + #if defined (HAVE_ADT) + #include "gdm-session-solaris-auditor.h" + #elif defined (HAVE_LIBAUDIT) + #include "gdm-session-linux-auditor.h" + #else + #include "gdm-session-auditor.h" + #endif + + #include "gdm-session-settings.h" + + #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate)) + + #define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" + #define GDM_SESSION_DBUS_NAME "org.gnome.DisplayManager.Session" + #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" + + #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker" + + #ifndef GDM_PASSWD_AUXILLARY_BUFFER_SIZE + #define GDM_PASSWD_AUXILLARY_BUFFER_SIZE 1024 + #endif + + #ifndef GDM_SESSION_DEFAULT_PATH + #define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin" + #endif + +@@ -1028,72 +1029,60 @@ gdm_session_worker_set_state (GdmSessionWorker *worker, + + static void + gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, + int status) + { + g_debug ("GdmSessionWorker: uninitializing PAM"); + + if (worker->priv->pam_handle == NULL) + return; + + gdm_session_worker_get_username (worker, NULL); + + if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { + pam_close_session (worker->priv->pam_handle, 0); + gdm_session_auditor_report_logout (worker->priv->auditor); + } else { + gdm_session_auditor_report_login_failure (worker->priv->auditor, + status, + pam_strerror (worker->priv->pam_handle, status)); + } + + if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) { + pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED); + } + + pam_end (worker->priv->pam_handle, status); + worker->priv->pam_handle = NULL; + + gdm_session_worker_stop_auditor (worker); + +- /* If user-display-server is not enabled the login_vt is always +- * identical to the session_vt. So in that case we never need to +- * do a VT switch. */ +-#ifdef ENABLE_USER_DISPLAY_SERVER +- if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { +- /* Switch to the login VT if we are not the login screen. */ +- if (worker->priv->session_vt != GDM_INITIAL_VT) { +- jump_to_vt (worker, GDM_INITIAL_VT); +- } +- } +-#endif +- + worker->priv->session_vt = 0; + + g_debug ("GdmSessionWorker: state NONE"); + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE); + } + + static char * + _get_tty_for_pam (const char *x11_display_name, + const char *display_device) + { + #ifdef __sun + return g_strdup (display_device); + #else + return g_strdup (x11_display_name); + #endif + } + + #ifdef PAM_XAUTHDATA + static struct pam_xauth_data * + _get_xauth_for_pam (const char *x11_authority_file) + { + FILE *fh; + Xauth *auth = NULL; + struct pam_xauth_data *retval = NULL; + gsize len = sizeof (*retval) + 1; + + fh = fopen (x11_authority_file, "r"); + if (fh) { + auth = XauReadAuth (fh); + fclose (fh); +@@ -1752,86 +1741,155 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker, + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCREDITED); + } else { + gdm_session_worker_uninitialize_pam (worker, error_code); + } + + return ret; + } + + static const char * const * + gdm_session_worker_get_environment (GdmSessionWorker *worker) + { + return (const char * const *) pam_getenvlist (worker->priv->pam_handle); + } + + static gboolean + run_script (GdmSessionWorker *worker, + const char *dir) + { + /* scripts are for non-program sessions only */ + if (worker->priv->is_program_session) { + return TRUE; + } + + return gdm_run_script (dir, + worker->priv->username, + worker->priv->x11_display_name, + worker->priv->display_is_local? NULL : worker->priv->hostname, + worker->priv->x11_authority_file); + } + ++static void ++wait_until_dbus_signal_emission_to_manager_finishes (GdmSessionWorker *worker) ++{ ++ g_autoptr (GdmDBusPeer) peer_proxy = NULL; ++ g_autoptr (GError) error = NULL; ++ gboolean pinged; ++ ++ peer_proxy = gdm_dbus_peer_proxy_new_sync (worker->priv->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, ++ NULL, ++ "/org/freedesktop/DBus", ++ NULL, ++ &error); ++ ++ if (peer_proxy == NULL) { ++ g_debug ("GdmSessionWorker: could not create peer proxy to daemon: %s", ++ error->message); ++ return; ++ } ++ ++ pinged = gdm_dbus_peer_call_ping_sync (peer_proxy, NULL, &error); ++ ++ if (!pinged) { ++ g_debug ("GdmSessionWorker: could not ping daemon: %s", ++ error->message); ++ return; ++ } ++} ++ ++static void ++jump_back_to_initial_vt (GdmSessionWorker *worker) ++{ ++ if (worker->priv->session_vt == 0) ++ return; ++ ++ if (worker->priv->session_vt == GDM_INITIAL_VT) ++ return; ++ ++ if (g_strcmp0 (worker->priv->display_seat_id, "seat0") != 0) ++ return; ++ ++#ifdef ENABLE_USER_DISPLAY_SERVER ++ jump_to_vt (worker, GDM_INITIAL_VT); ++ worker->priv->session_vt = 0; ++#endif ++} ++ + static void + session_worker_child_watch (GPid pid, + int status, + GdmSessionWorker *worker) + { + g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)", + (int) pid, + WIFEXITED (status) ? "status" + : WIFSIGNALED (status) ? "signal" + : "unknown", + WIFEXITED (status) ? WEXITSTATUS (status) + : WIFSIGNALED (status) ? WTERMSIG (status) + : -1); + +- + gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); + ++ worker->priv->child_pid = -1; ++ worker->priv->child_watch_id = 0; ++ run_script (worker, GDMCONFDIR "/PostSession"); ++ + gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker), + worker->priv->service, + status); + + killpg (pid, SIGHUP); + +- worker->priv->child_pid = -1; +- worker->priv->child_watch_id = 0; +- run_script (worker, GDMCONFDIR "/PostSession"); ++ /* FIXME: It's important to give the manager an opportunity to process the ++ * session-exited emission above before switching VTs. ++ * ++ * This is because switching VTs makes the manager try to put a login screen ++ * up on VT 1, but it may actually want to try to auto login again in response ++ * to session-exited. ++ * ++ * This function just does a manager roundtrip over the bus to make sure the ++ * signal has been dispatched before jumping. ++ * ++ * Ultimately, we may want to improve the manager<->worker interface. ++ * ++ * See: ++ * ++ * https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/123 ++ * ++ * for some ideas and more discussion. ++ * ++ */ ++ wait_until_dbus_signal_emission_to_manager_finishes (worker); ++ ++ jump_back_to_initial_vt (worker); + } + + static void + gdm_session_worker_watch_child (GdmSessionWorker *worker) + { + g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid); + worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid, + (GChildWatchFunc)session_worker_child_watch, + worker); + + } + + static gboolean + _is_loggable_file (const char* filename) + { + struct stat file_info; + + if (g_lstat (filename, &file_info) < 0) { + return FALSE; + } + + return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0; + } + + static void + rotate_logs (const char *path, + guint n_copies) + { + int i; + +@@ -2401,60 +2459,61 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, + + flags = 0; + + if (worker->priv->is_program_session) { + flags |= PAM_SILENT; + } + + error_code = pam_open_session (worker->priv->pam_handle, flags); + + if (error_code != PAM_SUCCESS) { + g_set_error (error, + GDM_SESSION_WORKER_ERROR, + GDM_SESSION_WORKER_ERROR_OPENING_SESSION, + "%s", pam_strerror (worker->priv->pam_handle, error_code)); + goto out; + } + + g_debug ("GdmSessionWorker: state SESSION_OPENED"); + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_OPENED); + + session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID"); + + if (session_id != NULL) { + g_free (worker->priv->session_id); + worker->priv->session_id = session_id; + } + + out: + if (error_code != PAM_SUCCESS) { + gdm_session_worker_uninitialize_pam (worker, error_code); ++ worker->priv->session_vt = 0; + return FALSE; + } + + gdm_session_worker_get_username (worker, NULL); + gdm_session_auditor_report_login (worker->priv->auditor); + + return TRUE; + } + + static void + gdm_session_worker_set_server_address (GdmSessionWorker *worker, + const char *address) + { + g_free (worker->priv->server_address); + worker->priv->server_address = g_strdup (address); + } + + static void + gdm_session_worker_set_is_reauth_session (GdmSessionWorker *worker, + gboolean is_reauth_session) + { + worker->priv->is_reauth_session = is_reauth_session; + } + + static void + gdm_session_worker_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) + { +@@ -3565,60 +3624,62 @@ gdm_session_worker_unwatch_child (GdmSessionWorker *worker) + return; + + g_source_remove (worker->priv->child_watch_id); + worker->priv->child_watch_id = 0; + } + + + static void + gdm_session_worker_finalize (GObject *object) + { + GdmSessionWorker *worker; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_SESSION_WORKER (object)); + + worker = GDM_SESSION_WORKER (object); + + g_return_if_fail (worker->priv != NULL); + + gdm_session_worker_unwatch_child (worker); + + if (worker->priv->child_pid > 0) { + gdm_signal_pid (worker->priv->child_pid, SIGTERM); + gdm_wait_on_pid (worker->priv->child_pid); + } + + if (worker->priv->pam_handle != NULL) { + gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); + } + ++ jump_back_to_initial_vt (worker); ++ + g_clear_object (&worker->priv->user_settings); + g_free (worker->priv->service); + g_free (worker->priv->x11_display_name); + g_free (worker->priv->x11_authority_file); + g_free (worker->priv->display_device); + g_free (worker->priv->display_seat_id); + g_free (worker->priv->hostname); + g_free (worker->priv->username); + g_free (worker->priv->server_address); + g_strfreev (worker->priv->arguments); + g_strfreev (worker->priv->extensions); + + g_hash_table_unref (worker->priv->reauthentication_requests); + + G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object); + } + + GdmSessionWorker * + gdm_session_worker_new (const char *address, + gboolean is_reauth_session) + { + GObject *object; + + object = g_object_new (GDM_TYPE_SESSION_WORKER, + "server-address", address, + "is-reauth-session", is_reauth_session, + NULL); + + return GDM_SESSION_WORKER (object); + } +diff --git a/daemon/org.freedesktop.DBus.xml b/daemon/org.freedesktop.DBus.xml +new file mode 100644 +index 000000000..5e0814bde +--- /dev/null ++++ b/daemon/org.freedesktop.DBus.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.28.0 + diff --git a/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch b/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch index 0fb7dbd..79e7eda 100644 --- a/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch +++ b/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch @@ -1,4 +1,4 @@ -From ac45b0745db7a8e8cbdd3a2880c0e39f0f3681a3 Mon Sep 17 00:00:00 2001 +From 2724b4fd6d4ac527acc481f056f535141b63fe24 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 7 May 2019 15:57:43 +0100 Subject: [PATCH 49/51] GdmManager, GdmDisplay: Add RegisterSession method @@ -6,13 +6,13 @@ Subject: [PATCH 49/51] GdmManager, GdmDisplay: Add RegisterSession method Window managers can use this to register with GDM when they've finished starting up and started displaying. --- - daemon/gdm-display.c | 27 +++++++++++++++++++++++++++ + daemon/gdm-display.c | 24 ++++++++++++++++++++++++ daemon/gdm-manager.c | 30 ++++++++++++++++++++++++++++++ daemon/gdm-manager.xml | 3 +++ - 3 files changed, 60 insertions(+) + 3 files changed, 57 insertions(+) diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 1cef8c7c1..09cc2e116 100644 +index 1cef8c7c1..56799741d 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -64,82 +64,84 @@ struct GdmDisplayPrivate @@ -100,7 +100,7 @@ index 1cef8c7c1..09cc2e116 100644 return self->priv->creation_time; } -@@ -733,60 +735,71 @@ static void +@@ -733,60 +735,68 @@ static void _gdm_display_set_x11_display_number (GdmDisplay *self, int num) { @@ -135,11 +135,8 @@ index 1cef8c7c1..09cc2e116 100644 +_gdm_display_set_session_registered (GdmDisplay *self, + gboolean registered) +{ -+ GdmDisplayPrivate *priv; -+ -+ priv = gdm_display_get_instance_private (self); + g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no"); -+ priv->session_registered = registered; ++ self->priv->session_registered = registered; +} + static void @@ -172,7 +169,7 @@ index 1cef8c7c1..09cc2e116 100644 guint prop_id, const GValue *value, GParamSpec *pspec) -@@ -811,60 +824,63 @@ gdm_display_set_property (GObject *object, +@@ -811,60 +821,63 @@ gdm_display_set_property (GObject *object, case PROP_SESSION_CLASS: _gdm_display_set_session_class (self, g_value_get_string (value)); break; @@ -236,7 +233,7 @@ index 1cef8c7c1..09cc2e116 100644 g_value_set_string (value, self->priv->session_id); break; case PROP_SESSION_CLASS: -@@ -881,60 +897,63 @@ gdm_display_get_property (GObject *object, +@@ -881,60 +894,63 @@ gdm_display_get_property (GObject *object, break; case PROP_X11_DISPLAY_NAME: g_value_set_string (value, self->priv->x11_display_name); @@ -300,7 +297,7 @@ index 1cef8c7c1..09cc2e116 100644 GdmDisplay *self) { char *hostname; -@@ -1197,60 +1216,68 @@ gdm_display_class_init (GdmDisplayClass *klass) +@@ -1197,60 +1213,68 @@ gdm_display_class_init (GdmDisplayClass *klass) G_PARAM_READABLE)); g_object_class_install_property (object_class, @@ -550,5 +547,5 @@ index f11f3fb73..92ef1d02d 100644 -- -2.27.0 +2.28.0 diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index ca1c090..5679bd8 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -10,7 +10,7 @@ Name: gdm Epoch: 1 Version: 3.28.3 -Release: 34%{?dist} +Release: 39%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -110,6 +110,12 @@ Patch200049: 0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch Patch200050: 0050-Allow-sessions-to-register-with-GDM.patch Patch200051: 0051-display-Handle-failure-before-display-registration.patch +# CVE-2020-16125 +Patch210001: 0001-display-Exit-with-failure-if-loading-existing-users-.patch + +# CVE-2020-27837 +Patch220001: 0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch + Patch300001: 0001-manager-Don-t-leak-session-objects.patch Patch300002: 0002-session-Don-t-leak-remote-greeter-interface.patch Patch300003: 0003-xdmcp-display-factory-Clear-launch-environment-when-.patch @@ -419,6 +425,19 @@ fi %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Wed Jan 27 2021 Ray Strode - 3.28.3-39 +- Ensure login screen display server is is killed at log in +- Pull in fixes for two security issues + Resolves: #1918391 + +* Tue Nov 10 2020 Jonas Ådahl - 3.28.3-38 +- Re-add disabling Wayland for server GPUs + Related: #1670273 + +* Tue Nov 10 2020 Jonas Ådahl - 3.28.3-35 +- Stop disabling Wayland for server GPUs + Related: #1670273 + * Tue Sep 15 2020 Ray Strode - 3.28.3-34 - Fix file descriptor leak Resolves: #1877853