summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <withnall@endlessm.com>2018-04-26 11:14:48 +0100
committerPhilip Withnall <withnall@endlessm.com>2018-04-26 15:19:17 +0100
commit9cbfb560614a251edf6d965eb3724c6294bab3f0 (patch)
tree46bb49761ef35e1a0b88b96012a2cd4306c96d8e
parentf9f497a702733708b5bae9f76d89cf93a415e6e2 (diff)
downloadglib-9cbfb560614a251edf6d965eb3724c6294bab3f0.tar.gz
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 <withnall@endlessm.com> https://bugzilla.gnome.org/show_bug.cgi?id=773435
-rw-r--r--glib/gutils.c12
1 files changed, 12 insertions, 0 deletions
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);
}