Blame SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch

dfaa01
From e339ad74ca408c665a62bb4bd98dd1ef6caedd20 Mon Sep 17 00:00:00 2001
dfaa01
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
dfaa01
Date: Tue, 27 Oct 2020 15:14:27 +0100
dfaa01
Subject: [PATCH] display: Exit with failure if loading existing users fails
dfaa01
dfaa01
Given not having users may make GDM to launch initial setup, that
dfaa01
allows to create new users (potentially with sudo capabilities), it's
dfaa01
better to make look_for_existing_users() to return its status and only
dfaa01
if it didn't fail continue the gdm execution.
dfaa01
dfaa01
GHSL-2020-202
dfaa01
CVE-2020-16125
dfaa01
dfaa01
Fixes #642
dfaa01
---
dfaa01
 daemon/gdm-display.c | 12 ++++++++----
dfaa01
 1 file changed, 8 insertions(+), 4 deletions(-)
dfaa01
dfaa01
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
dfaa01
index 929fa13bd..1b60eb621 100644
dfaa01
--- a/daemon/gdm-display.c
dfaa01
+++ b/daemon/gdm-display.c
dfaa01
@@ -436,106 +436,110 @@ finish_idle (GdmDisplay *self)
dfaa01
 static void
dfaa01
 queue_finish (GdmDisplay *self)
dfaa01
 {
dfaa01
         if (self->priv->finish_idle_id == 0) {
dfaa01
                 self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self);
dfaa01
         }
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 _gdm_display_set_status (GdmDisplay *self,
dfaa01
                          int         status)
dfaa01
 {
dfaa01
         if (status != self->priv->status) {
dfaa01
                 self->priv->status = status;
dfaa01
                 g_object_notify (G_OBJECT (self), "status");
dfaa01
         }
dfaa01
 }
dfaa01
 
dfaa01
 static gboolean
dfaa01
 gdm_display_real_prepare (GdmDisplay *self)
dfaa01
 {
dfaa01
         g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
dfaa01
 
dfaa01
         g_debug ("GdmDisplay: prepare display");
dfaa01
 
dfaa01
         _gdm_display_set_status (self, GDM_DISPLAY_PREPARED);
dfaa01
 
dfaa01
         return TRUE;
dfaa01
 }
dfaa01
 
dfaa01
-static void
dfaa01
+static gboolean
dfaa01
 look_for_existing_users_sync (GdmDisplay *self)
dfaa01
 {
dfaa01
         g_autoptr (GVariant) result = NULL;
dfaa01
         g_autoptr (GVariant) result_child = NULL;
dfaa01
         g_autoptr (GError) error = NULL;
dfaa01
         gboolean has_no_users = FALSE;
dfaa01
 
dfaa01
         result = g_dbus_connection_call_sync (self->priv->connection,
dfaa01
                                               "org.freedesktop.Accounts",
dfaa01
                                               "/org/freedesktop/Accounts",
dfaa01
                                               "org.freedesktop.DBus.Properties",
dfaa01
                                               "Get",
dfaa01
                                               g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"),
dfaa01
                                               G_VARIANT_TYPE ("(v)"),
dfaa01
                                               G_DBUS_CALL_FLAGS_NONE,
dfaa01
                                               -1,
dfaa01
                                               NULL,
dfaa01
                                               &error);
dfaa01
 
dfaa01
         if (result == NULL) {
dfaa01
-                g_warning ("Failed to contact accountsservice: %s", error->message);
dfaa01
-                return;
dfaa01
+                g_critical ("Failed to contact accountsservice: %s", error->message);
dfaa01
+                goto out;
dfaa01
         }
dfaa01
 
dfaa01
         g_variant_get (result, "(v)", &result_child);
dfaa01
         has_no_users = g_variant_get_boolean (result_child);
dfaa01
         self->priv->have_existing_user_accounts = !has_no_users;
dfaa01
 
dfaa01
         g_debug ("GdmDisplay: machine does %shave existing user accounts",
dfaa01
                  has_no_users? "not " : "");
dfaa01
+out:
dfaa01
+        return result != NULL;
dfaa01
 }
dfaa01
 
dfaa01
 gboolean
dfaa01
 gdm_display_prepare (GdmDisplay *self)
dfaa01
 {
dfaa01
         gboolean ret;
dfaa01
 
dfaa01
         g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
dfaa01
 
dfaa01
         g_debug ("GdmDisplay: Preparing display: %s", self->priv->id);
dfaa01
 
dfaa01
         /* FIXME: we should probably do this in a more global place,
dfaa01
          * asynchronously
dfaa01
          */
dfaa01
-        look_for_existing_users_sync (self);
dfaa01
+        if (!look_for_existing_users_sync (self)) {
dfaa01
+                exit (EXIT_FAILURE);
dfaa01
+        }
dfaa01
 
dfaa01
         self->priv->doing_initial_setup = wants_initial_setup (self);
dfaa01
 
dfaa01
         g_object_ref (self);
dfaa01
         ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self);
dfaa01
         g_object_unref (self);
dfaa01
 
dfaa01
         return ret;
dfaa01
 }
dfaa01
 
dfaa01
 gboolean
dfaa01
 gdm_display_manage (GdmDisplay *self)
dfaa01
 {
dfaa01
         gboolean res;
dfaa01
 
dfaa01
         g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
dfaa01
 
dfaa01
         g_debug ("GdmDisplay: Managing display: %s", self->priv->id);
dfaa01
 
dfaa01
         /* If not explicitly prepared, do it now */
dfaa01
         if (self->priv->status == GDM_DISPLAY_UNMANAGED) {
dfaa01
                 res = gdm_display_prepare (self);
dfaa01
                 if (! res) {
dfaa01
                         return FALSE;
dfaa01
                 }
dfaa01
         }
dfaa01
 
dfaa01
         if (g_strcmp0 (self->priv->session_class, "greeter") == 0) {
dfaa01
                 if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) {
dfaa01
                         GDM_DISPLAY_GET_CLASS (self)->manage (self);
dfaa01
-- 
dfaa01
2.28.0
dfaa01