mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-23 07:08:17 -05:00
run: Convert all environment variables into bwrap arguments
This avoids some of them being filtered out by a setuid bwrap. It also means that if they came from an untrusted source, they cannot be used to inject arbitrary code into a non-setuid bwrap via mechanisms like LD_PRELOAD. Because they get bundled into a memfd or temporary file, they do not actually appear in argv, ensuring that they remain inaccessible to processes running under a different uid (which is important if their values are tokens or other secrets). Signed-off-by: Simon McVittie <smcv@collabora.com> Part-of: https://github.com/flatpak/flatpak/security/advisories/GHSA-4ppf-fxf6-vxg2
This commit is contained in:
committed by
Alexander Larsson
parent
fe95ef6fad
commit
6d1773d2a5
@@ -43,6 +43,8 @@ void flatpak_bwrap_unset_env (FlatpakBwrap *bwrap,
|
||||
const char *variable);
|
||||
void flatpak_bwrap_add_arg (FlatpakBwrap *bwrap,
|
||||
const char *arg);
|
||||
void flatpak_bwrap_take_arg (FlatpakBwrap *bwrap,
|
||||
char *arg);
|
||||
void flatpak_bwrap_add_noinherit_fd (FlatpakBwrap *bwrap,
|
||||
int fd);
|
||||
void flatpak_bwrap_add_fd (FlatpakBwrap *bwrap,
|
||||
@@ -73,6 +75,7 @@ void flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap,
|
||||
const char *type,
|
||||
const char *src,
|
||||
const char *dest);
|
||||
void flatpak_bwrap_envp_to_args (FlatpakBwrap *bwrap);
|
||||
gboolean flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap,
|
||||
int start,
|
||||
int end,
|
||||
|
||||
@@ -109,6 +109,18 @@ flatpak_bwrap_add_arg (FlatpakBwrap *bwrap, const char *arg)
|
||||
g_ptr_array_add (bwrap->argv, g_strdup (arg));
|
||||
}
|
||||
|
||||
/*
|
||||
* flatpak_bwrap_take_arg:
|
||||
* @arg: (transfer full): Take ownership of this argument
|
||||
*
|
||||
* Add @arg to @bwrap's argv, taking ownership of the pointer.
|
||||
*/
|
||||
void
|
||||
flatpak_bwrap_take_arg (FlatpakBwrap *bwrap, char *arg)
|
||||
{
|
||||
g_ptr_array_add (bwrap->argv, arg);
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_bwrap_finish (FlatpakBwrap *bwrap)
|
||||
{
|
||||
@@ -274,6 +286,37 @@ flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert bwrap->envp into a series of --setenv arguments for bwrap(1),
|
||||
* assumed to be applied to an empty environment. Reset envp to be an
|
||||
* empty environment.
|
||||
*/
|
||||
void
|
||||
flatpak_bwrap_envp_to_args (FlatpakBwrap *bwrap)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
for (i = 0; bwrap->envp[i] != NULL; i++)
|
||||
{
|
||||
char *key_val = bwrap->envp[i];
|
||||
char *eq = strchr (key_val, '=');
|
||||
|
||||
if (eq)
|
||||
{
|
||||
flatpak_bwrap_add_arg (bwrap, "--setenv");
|
||||
flatpak_bwrap_take_arg (bwrap, g_strndup (key_val, eq - key_val));
|
||||
flatpak_bwrap_add_arg (bwrap, eq + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (g_steal_pointer (&bwrap->envp));
|
||||
bwrap->envp = g_strdupv (flatpak_bwrap_empty_env);
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap,
|
||||
int start,
|
||||
|
||||
@@ -1463,24 +1463,6 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap,
|
||||
flatpak_run_add_system_dbus_args (bwrap, proxy_arg_bwrap, context, flags);
|
||||
flatpak_run_add_a11y_dbus_args (bwrap, proxy_arg_bwrap, context, flags);
|
||||
|
||||
if (g_environ_getenv (bwrap->envp, "LD_LIBRARY_PATH") != NULL)
|
||||
{
|
||||
/* LD_LIBRARY_PATH is overridden for setuid helper, so pass it as cmdline arg */
|
||||
flatpak_bwrap_add_args (bwrap,
|
||||
"--setenv", "LD_LIBRARY_PATH", g_environ_getenv (bwrap->envp, "LD_LIBRARY_PATH"),
|
||||
NULL);
|
||||
flatpak_bwrap_unset_env (bwrap, "LD_LIBRARY_PATH");
|
||||
}
|
||||
|
||||
if (g_environ_getenv (bwrap->envp, "TMPDIR") != NULL)
|
||||
{
|
||||
/* TMPDIR is overridden for setuid helper, so pass it as cmdline arg */
|
||||
flatpak_bwrap_add_args (bwrap,
|
||||
"--setenv", "TMPDIR", g_environ_getenv (bwrap->envp, "TMPDIR"),
|
||||
NULL);
|
||||
flatpak_bwrap_unset_env (bwrap, "TMPDIR");
|
||||
}
|
||||
|
||||
/* Must run this before spawning the dbus proxy, to ensure it
|
||||
ends up in the app cgroup */
|
||||
if (!flatpak_run_in_transient_unit (app_id, &my_error))
|
||||
@@ -4068,6 +4050,8 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
command = default_command;
|
||||
}
|
||||
|
||||
flatpak_bwrap_envp_to_args (bwrap);
|
||||
|
||||
if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -4098,6 +4082,12 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
/* We use LEAVE_DESCRIPTORS_OPEN to work around dead-lock, see flatpak_close_fds_workaround */
|
||||
spawn_flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
|
||||
|
||||
/* flatpak_bwrap_envp_to_args() moved the environment variables to
|
||||
* be set into --setenv instructions in argv, so the environment
|
||||
* in which the bwrap command runs must be empty. */
|
||||
g_assert (bwrap->envp != NULL);
|
||||
g_assert (bwrap->envp[0] == NULL);
|
||||
|
||||
if (!g_spawn_async (NULL,
|
||||
(char **) bwrap->argv->pdata,
|
||||
bwrap->envp,
|
||||
@@ -4125,6 +4115,12 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
* we do want to allow inheriting fds into flatpak run. */
|
||||
flatpak_bwrap_child_setup (bwrap->fds, FALSE);
|
||||
|
||||
/* flatpak_bwrap_envp_to_args() moved the environment variables to
|
||||
* be set into --setenv instructions in argv, so the environment
|
||||
* in which the bwrap command runs must be empty. */
|
||||
g_assert (bwrap->envp != NULL);
|
||||
g_assert (bwrap->envp[0] == NULL);
|
||||
|
||||
if (execvpe (flatpak_get_bwrap (), (char **) bwrap->argv->pdata, bwrap->envp) == -1)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||
|
||||
Reference in New Issue
Block a user