mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-15 05:46:15 +01:00
Merge branch 'backport-1862-gio-envvars-glib-2-66' into 'glib-2-66'
Backport !1862 “gio: Ignore various environment variables when running as setuid” to glib-2-66 See merge request GNOME/glib!1864
This commit is contained in:
commit
13732f800c
@ -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
|
modules from this alternate directory instead of the directory
|
||||||
built into GIO. This is useful when running tests, for example.
|
built into GIO. This is useful when running tests, for example.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This environment variable is ignored when running in a setuid program.
|
||||||
|
</para>
|
||||||
</formalpara>
|
</formalpara>
|
||||||
|
|
||||||
<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
|
paths separated by a colon, GIO will attempt to load
|
||||||
additional modules from within the path.
|
additional modules from within the path.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This environment variable is ignored when running in a setuid program.
|
||||||
|
</para>
|
||||||
</formalpara>
|
</formalpara>
|
||||||
|
|
||||||
<formalpara>
|
<formalpara>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "gdbusaddress.h"
|
#include "gdbusaddress.h"
|
||||||
#include "gdbuserror.h"
|
#include "gdbuserror.h"
|
||||||
#include "gioenumtypes.h"
|
#include "gioenumtypes.h"
|
||||||
|
#include "glib-private.h"
|
||||||
#include "gnetworkaddress.h"
|
#include "gnetworkaddress.h"
|
||||||
#include "gsocketclient.h"
|
#include "gsocketclient.h"
|
||||||
#include "giostream.h"
|
#include "giostream.h"
|
||||||
@ -1279,6 +1280,7 @@ g_dbus_address_get_for_bus_sync (GBusType bus_type,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
|
||||||
gchar *ret, *s = NULL;
|
gchar *ret, *s = NULL;
|
||||||
const gchar *starter_bus;
|
const gchar *starter_bus;
|
||||||
GError *local_error;
|
GError *local_error;
|
||||||
@ -1317,10 +1319,12 @@ g_dbus_address_get_for_bus_sync (GBusType bus_type,
|
|||||||
_g_dbus_debug_print_unlock ();
|
_g_dbus_debug_print_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don’t load the addresses from the environment if running as setuid, as they
|
||||||
|
* come from an unprivileged caller. */
|
||||||
switch (bus_type)
|
switch (bus_type)
|
||||||
{
|
{
|
||||||
case G_BUS_TYPE_SYSTEM:
|
case G_BUS_TYPE_SYSTEM:
|
||||||
ret = g_strdup (g_getenv ("DBUS_SYSTEM_BUS_ADDRESS"));
|
ret = !is_setuid ? g_strdup (g_getenv ("DBUS_SYSTEM_BUS_ADDRESS")) : NULL;
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
ret = g_strdup ("unix:path=/var/run/dbus/system_bus_socket");
|
ret = g_strdup ("unix:path=/var/run/dbus/system_bus_socket");
|
||||||
@ -1328,7 +1332,7 @@ g_dbus_address_get_for_bus_sync (GBusType bus_type,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case G_BUS_TYPE_SESSION:
|
case G_BUS_TYPE_SESSION:
|
||||||
ret = g_strdup (g_getenv ("DBUS_SESSION_BUS_ADDRESS"));
|
ret = !is_setuid ? g_strdup (g_getenv ("DBUS_SESSION_BUS_ADDRESS")) : NULL;
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
ret = get_session_address_platform_specific (&local_error);
|
ret = get_session_address_platform_specific (&local_error);
|
||||||
|
@ -305,6 +305,27 @@ desktop_file_dir_app_name_is_masked (DesktopFileDir *dir,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not much to go on from https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
|
||||||
|
* so validate it as a non-empty alphanumeric ASCII string with `-` and `_` allowed.
|
||||||
|
*
|
||||||
|
* Validation is important as the desktop IDs are used to construct filenames,
|
||||||
|
* and may be set by an unprivileged caller if running in a setuid program. */
|
||||||
|
static gboolean
|
||||||
|
validate_xdg_desktop (const gchar *desktop)
|
||||||
|
{
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
for (i = 0; desktop[i] != '\0'; i++)
|
||||||
|
if (desktop[i] != '-' && desktop[i] != '_' &&
|
||||||
|
!g_ascii_isalnum (desktop[i]))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static const gchar * const *
|
static const gchar * const *
|
||||||
get_lowercase_current_desktops (void)
|
get_lowercase_current_desktops (void)
|
||||||
{
|
{
|
||||||
@ -320,12 +341,22 @@ get_lowercase_current_desktops (void)
|
|||||||
if (envvar)
|
if (envvar)
|
||||||
{
|
{
|
||||||
gint i, j;
|
gint i, j;
|
||||||
|
gsize tmp_len;
|
||||||
|
|
||||||
tmp = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0);
|
tmp = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0);
|
||||||
|
tmp_len = g_strv_length (tmp);
|
||||||
|
|
||||||
for (i = 0; tmp[i]; i++)
|
for (i = 0; tmp[i]; i++)
|
||||||
for (j = 0; tmp[i][j]; j++)
|
{
|
||||||
tmp[i][j] = g_ascii_tolower (tmp[i][j]);
|
/* If the desktop is invalid, drop it and shift the following
|
||||||
|
* ones (and trailing %NULL) up. */
|
||||||
|
if (!validate_xdg_desktop (tmp[i]))
|
||||||
|
memmove (tmp + i, tmp + i + 1, tmp_len - i);
|
||||||
|
|
||||||
|
/* Convert to lowercase. */
|
||||||
|
for (j = 0; tmp[i][j]; j++)
|
||||||
|
tmp[i][j] = g_ascii_tolower (tmp[i][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tmp = g_new0 (gchar *, 0 + 1);
|
tmp = g_new0 (gchar *, 0 + 1);
|
||||||
@ -344,6 +375,7 @@ get_current_desktops (const gchar *value)
|
|||||||
if (g_once_init_enter (&result))
|
if (g_once_init_enter (&result))
|
||||||
{
|
{
|
||||||
gchar **tmp;
|
gchar **tmp;
|
||||||
|
gsize tmp_len, i;
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
value = g_getenv ("XDG_CURRENT_DESKTOP");
|
value = g_getenv ("XDG_CURRENT_DESKTOP");
|
||||||
@ -352,6 +384,15 @@ get_current_desktops (const gchar *value)
|
|||||||
value = "";
|
value = "";
|
||||||
|
|
||||||
tmp = g_strsplit (value, ":", 0);
|
tmp = g_strsplit (value, ":", 0);
|
||||||
|
tmp_len = g_strv_length (tmp);
|
||||||
|
|
||||||
|
for (i = 0; tmp[i]; i++)
|
||||||
|
{
|
||||||
|
/* If the desktop is invalid, drop it and shift the following
|
||||||
|
* ones (and trailing %NULL) up. */
|
||||||
|
if (!validate_xdg_desktop (tmp[i]))
|
||||||
|
memmove (tmp + i, tmp + i + 1, tmp_len - i);
|
||||||
|
}
|
||||||
|
|
||||||
g_once_init_leave (&result, tmp);
|
g_once_init_leave (&result, tmp);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "giomodule.h"
|
#include "giomodule.h"
|
||||||
#include "giomodule-priv.h"
|
#include "giomodule-priv.h"
|
||||||
|
#include "glib-private.h"
|
||||||
#include "glocalfilemonitor.h"
|
#include "glocalfilemonitor.h"
|
||||||
#include "gnativevolumemonitor.h"
|
#include "gnativevolumemonitor.h"
|
||||||
#include "gproxyresolver.h"
|
#include "gproxyresolver.h"
|
||||||
@ -806,6 +807,9 @@ _g_io_module_get_default_type (const gchar *extension_point,
|
|||||||
return G_TYPE_INVALID;
|
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;
|
use_this = envvar ? g_getenv (envvar) : NULL;
|
||||||
if (g_strcmp0 (use_this, "help") == 0)
|
if (g_strcmp0 (use_this, "help") == 0)
|
||||||
{
|
{
|
||||||
@ -955,6 +959,9 @@ _g_io_module_get_default (const gchar *extension_point,
|
|||||||
return NULL;
|
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;
|
use_this = envvar ? g_getenv (envvar) : NULL;
|
||||||
if (g_strcmp0 (use_this, "help") == 0)
|
if (g_strcmp0 (use_this, "help") == 0)
|
||||||
{
|
{
|
||||||
@ -1150,8 +1157,16 @@ static gchar *
|
|||||||
get_gio_module_dir (void)
|
get_gio_module_dir (void)
|
||||||
{
|
{
|
||||||
gchar *module_dir;
|
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)
|
if (module_dir == NULL)
|
||||||
{
|
{
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
@ -1183,13 +1198,14 @@ _g_io_modules_ensure_loaded (void)
|
|||||||
|
|
||||||
if (!loaded_dirs)
|
if (!loaded_dirs)
|
||||||
{
|
{
|
||||||
|
gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
|
||||||
gchar *module_dir;
|
gchar *module_dir;
|
||||||
|
|
||||||
loaded_dirs = TRUE;
|
loaded_dirs = TRUE;
|
||||||
scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
|
scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
|
||||||
|
|
||||||
/* First load any overrides, extras */
|
/* First load any overrides, extras (but not if running as setuid!) */
|
||||||
module_path = g_getenv ("GIO_EXTRA_MODULES");
|
module_path = !is_setuid ? g_getenv ("GIO_EXTRA_MODULES") : NULL;
|
||||||
if (module_path)
|
if (module_path)
|
||||||
{
|
{
|
||||||
gchar **paths;
|
gchar **paths;
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include <gio/gzlibdecompressor.h>
|
#include <gio/gzlibdecompressor.h>
|
||||||
#include <gio/gconverterinputstream.h>
|
#include <gio/gconverterinputstream.h>
|
||||||
|
|
||||||
|
#include "glib-private.h"
|
||||||
|
|
||||||
struct _GResource
|
struct _GResource
|
||||||
{
|
{
|
||||||
int ref_count;
|
int ref_count;
|
||||||
@ -159,7 +161,7 @@ G_DEFINE_BOXED_TYPE (GResource, g_resource, g_resource_ref, g_resource_unref)
|
|||||||
* replace resources in the program or library, without recompiling, for debugging or quick hacking and testing
|
* replace resources in the program or library, without recompiling, for debugging or quick hacking and testing
|
||||||
* purposes. Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment variable to selectively overlay
|
* purposes. Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment variable to selectively overlay
|
||||||
* resources with replacements from the filesystem. It is a %G_SEARCHPATH_SEPARATOR-separated list of substitutions to perform
|
* resources with replacements from the filesystem. It is a %G_SEARCHPATH_SEPARATOR-separated list of substitutions to perform
|
||||||
* during resource lookups.
|
* during resource lookups. It is ignored when running in a setuid process.
|
||||||
*
|
*
|
||||||
* A substitution has the form
|
* A substitution has the form
|
||||||
*
|
*
|
||||||
@ -330,10 +332,13 @@ g_resource_find_overlay (const gchar *path,
|
|||||||
|
|
||||||
if (g_once_init_enter (&overlay_dirs))
|
if (g_once_init_enter (&overlay_dirs))
|
||||||
{
|
{
|
||||||
|
gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
|
||||||
const gchar * const *result;
|
const gchar * const *result;
|
||||||
const gchar *envvar;
|
const gchar *envvar;
|
||||||
|
|
||||||
envvar = g_getenv ("G_RESOURCE_OVERLAYS");
|
/* Don’t load overlays if setuid, as they could allow reading privileged
|
||||||
|
* files. */
|
||||||
|
envvar = !is_setuid ? g_getenv ("G_RESOURCE_OVERLAYS") : NULL;
|
||||||
if (envvar != NULL)
|
if (envvar != NULL)
|
||||||
{
|
{
|
||||||
gchar **parts;
|
gchar **parts;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "glib-private.h"
|
||||||
#include "gsettingsschema-internal.h"
|
#include "gsettingsschema-internal.h"
|
||||||
#include "gsettings.h"
|
#include "gsettings.h"
|
||||||
|
|
||||||
@ -343,6 +344,7 @@ initialise_schema_sources (void)
|
|||||||
*/
|
*/
|
||||||
if G_UNLIKELY (g_once_init_enter (&initialised))
|
if G_UNLIKELY (g_once_init_enter (&initialised))
|
||||||
{
|
{
|
||||||
|
gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
|
||||||
const gchar * const *dirs;
|
const gchar * const *dirs;
|
||||||
const gchar *path;
|
const gchar *path;
|
||||||
gchar **extra_schema_dirs;
|
gchar **extra_schema_dirs;
|
||||||
@ -357,7 +359,9 @@ initialise_schema_sources (void)
|
|||||||
|
|
||||||
try_prepend_data_dir (g_get_user_data_dir ());
|
try_prepend_data_dir (g_get_user_data_dir ());
|
||||||
|
|
||||||
if ((path = g_getenv ("GSETTINGS_SCHEMA_DIR")) != NULL)
|
/* Disallow loading extra schemas if running as setuid, as that could
|
||||||
|
* allow reading privileged files. */
|
||||||
|
if (!is_setuid && (path = g_getenv ("GSETTINGS_SCHEMA_DIR")) != NULL)
|
||||||
{
|
{
|
||||||
extra_schema_dirs = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 0);
|
extra_schema_dirs = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 0);
|
||||||
for (i = 0; extra_schema_dirs[i]; i++);
|
for (i = 0; extra_schema_dirs[i]; i++);
|
||||||
|
Loading…
Reference in New Issue
Block a user