From 9cbfb560614a251edf6d965eb3724c6294bab3f0 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 26 Apr 2018 11:14:48 +0100 Subject: [PATCH] gutils: Fix deadlock if g_get_home_dir() fails when called twice If g_get_home_dir() calculated a NULL home directory (due to $HOME being unset and /etc/passwd being inaccessible, for example due to an overly-zealous LSM), it would call g_once_init_leave (&home_dir, NULL), which would emit a critical and fail to leave the GOnce critical section. That meant that the following call to g_get_home_dir() would deadlock in g_once_init_enter(). Fix that by setting the home directory to a made-up value in such cases (which the documentation handily already explicitly allows). Thanks to Simon McVittie for the analysis leading to an easy patch. Signed-off-by: Philip Withnall https://bugzilla.gnome.org/show_bug.cgi?id=773435 --- glib/gutils.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/glib/gutils.c b/glib/gutils.c index de4401ad3..5813b2281 100644 --- a/glib/gutils.c +++ b/glib/gutils.c @@ -883,6 +883,18 @@ g_get_home_dir (void) tmp = entry->home_dir; } + /* If we have been denied access to /etc/passwd (for example, by an + * overly-zealous LSM), make up a junk value. The return value at this + * point is explicitly documented as ‘undefined’. Memory management is as + * immediately above: strictly this should be copied, but we know not + * copying it is OK. */ + if (tmp == NULL) + { + g_warning ("Could not find home directory: $HOME is not set, and " + "user database could not be read."); + tmp = "/"; + } + g_once_init_leave (&home_dir, tmp); }