diff --git a/docs/reference/gio/overview.xml b/docs/reference/gio/overview.xml index 7817ab60f..d82f1ac94 100644 --- a/docs/reference/gio/overview.xml +++ b/docs/reference/gio/overview.xml @@ -436,6 +436,9 @@ Gvfs is also heavily distributed and relies on a session bus to be present. modules from this alternate directory instead of the directory built into GIO. This is useful when running tests, for example. + + This environment variable is ignored when running in a setuid program. + @@ -446,6 +449,9 @@ Gvfs is also heavily distributed and relies on a session bus to be present. paths separated by a colon, GIO will attempt to load additional modules from within the path. + + This environment variable is ignored when running in a setuid program. + diff --git a/gio/giomodule.c b/gio/giomodule.c index dc4d6d3b3..aaf46364c 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -30,6 +30,7 @@ #include "giomodule.h" #include "giomodule-priv.h" +#include "glib-private.h" #include "glocalfilemonitor.h" #include "gnativevolumemonitor.h" #include "gproxyresolver.h" @@ -806,6 +807,9 @@ _g_io_module_get_default_type (const gchar *extension_point, return G_TYPE_INVALID; } + /* It’s OK to query the environment here, even when running as setuid, because + * it only allows a choice between existing already-loaded modules. No new + * code is loaded based on the environment variable value. */ use_this = envvar ? g_getenv (envvar) : NULL; if (g_strcmp0 (use_this, "help") == 0) { @@ -955,6 +959,9 @@ _g_io_module_get_default (const gchar *extension_point, return NULL; } + /* It’s OK to query the environment here, even when running as setuid, because + * it only allows a choice between existing already-loaded modules. No new + * code is loaded based on the environment variable value. */ use_this = envvar ? g_getenv (envvar) : NULL; if (g_strcmp0 (use_this, "help") == 0) { @@ -1150,8 +1157,16 @@ static gchar * get_gio_module_dir (void) { gchar *module_dir; + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); - module_dir = g_strdup (g_getenv ("GIO_MODULE_DIR")); + /* If running as setuid, loading modules from an arbitrary directory + * controlled by the unprivileged user who is running the program could allow + * for execution of arbitrary code (in constructors in modules). + * Don’t allow it. + * + * If a setuid program somehow needs to load additional GIO modules, it should + * explicitly call g_io_modules_scan_all_in_directory(). */ + module_dir = !is_setuid ? g_strdup (g_getenv ("GIO_MODULE_DIR")) : NULL; if (module_dir == NULL) { #ifdef G_OS_WIN32 @@ -1183,13 +1198,14 @@ _g_io_modules_ensure_loaded (void) if (!loaded_dirs) { + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); gchar *module_dir; loaded_dirs = TRUE; scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES); - /* First load any overrides, extras */ - module_path = g_getenv ("GIO_EXTRA_MODULES"); + /* First load any overrides, extras (but not if running as setuid!) */ + module_path = !is_setuid ? g_getenv ("GIO_EXTRA_MODULES") : NULL; if (module_path) { gchar **paths;