[glib: 1/6] giomodule: Ignore GIO_MODULE_DIR when running as setuid
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/6] giomodule: Ignore GIO_MODULE_DIR when running as setuid
- Date: Thu, 7 Jan 2021 15:15:48 +0000 (UTC)
commit ba414ee1008eac9a27b6a5ecf137a29ff147ccf8
Author: Philip Withnall <pwithnall endlessos org>
Date: Fri Dec 4 23:33:43 2020 +0000
giomodule: Ignore GIO_MODULE_DIR when running as setuid
Even if the modules in the given directory never get chosen to be used,
loading arbitrary code from a user-provided directory is not safe when
running as setuid, as the process’ environment comes from an untrusted
source.
Also ignore `GIO_EXTRA_MODULES`.
Spotted by Simon McVittie.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
Fixes: #2168
docs/reference/gio/overview.xml | 6 ++++++
gio/giomodule.c | 24 ++++++++++++++++++++----
2 files changed, 26 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gio/overview.xml b/docs/reference/gio/overview.xml
index b44228586..816afb9d3 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.
</para>
+ <para>
+ This environment variable is ignored when running in a setuid program.
+ </para>
</formalpara>
<formalpara>
@@ -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.
</para>
+ <para>
+ This environment variable is ignored when running in a setuid program.
+ </para>
</formalpara>
<formalpara>
diff --git a/gio/giomodule.c b/gio/giomodule.c
index f20b64875..4c4c75b90 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"
@@ -812,6 +813,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)
{
@@ -961,6 +965,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)
{
@@ -1159,8 +1166,16 @@ static gchar *
get_gio_module_dir (void)
{
gchar *module_dir;
-
- module_dir = g_strdup (g_getenv ("GIO_MODULE_DIR"));
+ gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
+
+ /* 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
@@ -1192,13 +1207,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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]