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

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