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