157 lines
5.8 KiB
Diff
157 lines
5.8 KiB
Diff
From b04ab0f0c4fe4970737187a76389b20029e27488 Mon Sep 17 00:00:00 2001
|
|
From: Simon McVittie <smcv@collabora.com>
|
|
Date: Tue, 12 Jan 2021 12:21:31 +0000
|
|
Subject: [PATCH] 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
|
|
---
|
|
common/flatpak-bwrap-private.h | 3 +++
|
|
common/flatpak-bwrap.c | 43 ++++++++++++++++++++++++++++++++++
|
|
common/flatpak-run.c | 24 ++++++++++++-------
|
|
3 files changed, 61 insertions(+), 9 deletions(-)
|
|
|
|
--- flatpak.orig/common/flatpak-bwrap-private.h
|
|
+++ flatpak/common/flatpak-bwrap-private.h
|
|
@@ -43,6 +43,8 @@ void flatpak_bwrap_unset_env (F
|
|
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
|
|
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,
|
|
--- flatpak.orig/common/flatpak-bwrap.c
|
|
+++ flatpak/common/flatpak-bwrap.c
|
|
@@ -108,6 +108,18 @@ flatpak_bwrap_add_arg (FlatpakBwrap *bwr
|
|
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)
|
|
{
|
|
@@ -273,6 +285,37 @@ flatpak_bwrap_add_bind_arg (FlatpakBwrap
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * 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,
|
|
--- flatpak.orig/common/flatpak-run.c
|
|
+++ flatpak/common/flatpak-run.c
|
|
@@ -1120,15 +1120,6 @@ flatpak_run_add_environment_args (Flatpa
|
|
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");
|
|
- }
|
|
-
|
|
/* 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))
|
|
@@ -3139,6 +3130,8 @@ flatpak_run_app (const char *app_ref
|
|
command = default_command;
|
|
}
|
|
|
|
+ flatpak_bwrap_envp_to_args (bwrap);
|
|
+
|
|
if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
|
|
return FALSE;
|
|
|
|
@@ -3161,6 +3154,12 @@ flatpak_run_app (const char *app_ref
|
|
char pid_str[64];
|
|
g_autofree char *pid_path = NULL;
|
|
|
|
+ /* 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,
|
|
@@ -3185,6 +3184,13 @@ flatpak_run_app (const char *app_ref
|
|
|
|
/* Ensure we unset O_CLOEXEC */
|
|
flatpak_bwrap_child_setup_cb (bwrap->fds);
|
|
+
|
|
+ /* 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),
|