From 7a93013153a425d4cb8466cd9b665b98e713451d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sun, 10 Jan 2021 16:18:58 +0000 Subject: [PATCH] context: Add --env-fd option This allows environment variables to be added to the context without making their values visible to processes running under a different uid, which might be significant if the variable's value is a token or some other secret value. Signed-off-by: Simon McVittie Part-of: https://github.com/flatpak/flatpak/security/advisories/GHSA-4ppf-fxf6-vxg2 --- common/flatpak-context.c | 60 ++++++++++++++++++++++++++++++++++++ doc/flatpak-build-finish.xml | 18 +++++++++++ doc/flatpak-build.xml | 18 +++++++++++ doc/flatpak-override.xml | 18 +++++++++++ doc/flatpak-run.xml | 18 +++++++++++ 5 files changed, 132 insertions(+) --- flatpak.orig/common/flatpak-context.c +++ flatpak/common/flatpak-context.c @@ -1040,6 +1040,65 @@ option_env_cb (const gchar *option_name, } static gboolean +option_env_fd_cb (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + FlatpakContext *context = data; + g_autoptr(GBytes) env_block = NULL; + gsize remaining; + const char *p; + guint64 fd; + gchar *endptr; + + fd = g_ascii_strtoull (value, &endptr, 10); + + if (endptr == NULL || *endptr != '\0' || fd > G_MAXINT) + return glnx_throw (error, "Not a valid file descriptor: %s", value); + + env_block = glnx_fd_readall_bytes ((int) fd, NULL, error); + + if (env_block == NULL) + return FALSE; + + p = g_bytes_get_data (env_block, &remaining); + + /* env_block might not be \0-terminated */ + while (remaining > 0) + { + size_t len = strnlen (p, remaining); + const char *equals; + + g_assert (len <= remaining); + + equals = memchr (p, '=', len); + + if (equals == NULL || equals == p) + return glnx_throw (error, + "Environment variable must be given in the form VARIABLE=VALUE, not %.*s", (int) len, p); + + flatpak_context_set_env_var (context, + g_strndup (p, equals - p), + g_strndup (equals + 1, len - (equals - p) - 1)); + p += len; + remaining -= len; + + if (remaining > 0) + { + g_assert (*p == '\0'); + p += 1; + remaining -= 1; + } + } + + if (fd >= 3) + close (fd); + + return TRUE; +} + +static gboolean option_own_name_cb (const gchar *option_name, const gchar *value, gpointer data, @@ -1206,6 +1265,7 @@ static GOptionEntry context_options[] = { "filesystem", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_filesystem_cb, N_("Expose filesystem to app (:ro for read-only)"), N_("FILESYSTEM[:ro]") }, { "nofilesystem", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nofilesystem_cb, N_("Don't expose filesystem to app"), N_("FILESYSTEM") }, { "env", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_cb, N_("Set environment variable"), N_("VAR=VALUE") }, + { "env-fd", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_fd_cb, N_("Read environment variables in env -0 format from FD"), N_("FD") }, { "own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_own_name_cb, N_("Allow app to own name on the session bus"), N_("DBUS_NAME") }, { "talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_talk_name_cb, N_("Allow app to talk to name on the session bus"), N_("DBUS_NAME") }, { "system-own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_own_name_cb, N_("Allow app to own name on the system bus"), N_("DBUS_NAME") }, --- flatpak.orig/doc/flatpak-build-finish.xml +++ flatpak/doc/flatpak-build-finish.xml @@ -277,6 +277,24 @@ key=v1;v2; + + + + Read environment variables from the file descriptor + FD, and set them as if + via . This can be used to avoid + environment variables and their values becoming visible + to other users. + + Each environment variable is in the form + VAR=VALUE + followed by a zero byte. This is the same format used by + env -0 and + /proc/*/environ. + + + + --- flatpak.orig/doc/flatpak-build.xml +++ flatpak/doc/flatpak-build.xml @@ -284,6 +284,24 @@ key=v1;v2; + + + + Read environment variables from the file descriptor + FD, and set them as if + via . This can be used to avoid + environment variables and their values becoming visible + to other users. + + Each environment variable is in the form + VAR=VALUE + followed by a zero byte. This is the same format used by + env -0 and + /proc/*/environ. + + + + --- flatpak.orig/doc/flatpak-override.xml +++ flatpak/doc/flatpak-override.xml @@ -258,6 +258,24 @@ key=v1;v2; + + + + Read environment variables from the file descriptor + FD, and set them as if + via . This can be used to avoid + environment variables and their values becoming visible + to other users. + + Each environment variable is in the form + VAR=VALUE + followed by a zero byte. This is the same format used by + env -0 and + /proc/*/environ. + + + + --- flatpak.orig/doc/flatpak-run.xml +++ flatpak/doc/flatpak-run.xml @@ -361,6 +361,24 @@ key=v1;v2; + + + + Read environment variables from the file descriptor + FD, and set them as if + via . This can be used to avoid + environment variables and their values becoming visible + to other users. + + Each environment variable is in the form + VAR=VALUE + followed by a zero byte. This is the same format used by + env -0 and + /proc/*/environ. + + + +