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
This commit is contained in:
Philip Withnall 2018-04-26 11:14:48 +01:00
parent f9f497a702
commit 9cbfb56061

View File

@ -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);
}