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 <smcv@collabora.com>
Part-of: https://github.com/flatpak/flatpak/security/advisories/GHSA-4ppf-fxf6-vxg2
This commit is contained in:
Simon McVittie
2021-01-10 16:18:58 +00:00
committed by Alexander Larsson
parent 6a11007021
commit 57416f3806
5 changed files with 132 additions and 0 deletions

View File

@@ -1045,6 +1045,65 @@ option_env_cb (const gchar *option_name,
return TRUE;
}
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,
@@ -1242,6 +1301,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") },
{ "no-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_no_talk_name_cb, N_("Don't allow app to talk to name on the session bus"), N_("DBUS_NAME") },

View File

@@ -286,6 +286,24 @@ key=v1;v2;
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--env-fd=<replaceable>FD</replaceable></option></term>
<listitem><para>
Read environment variables from the file descriptor
<replaceable>FD</replaceable>, and set them as if
via <option>--env</option>. This can be used to avoid
environment variables and their values becoming visible
to other users.
</para><para>
Each environment variable is in the form
<replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
followed by a zero byte. This is the same format used by
<literal>env -0</literal> and
<filename>/proc/*/environ</filename>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--own-name=NAME</option></term>

View File

@@ -288,6 +288,24 @@ key=v1;v2;
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--env-fd=<replaceable>FD</replaceable></option></term>
<listitem><para>
Read environment variables from the file descriptor
<replaceable>FD</replaceable>, and set them as if
via <option>--env</option>. This can be used to avoid
environment variables and their values becoming visible
to other users.
</para><para>
Each environment variable is in the form
<replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
followed by a zero byte. This is the same format used by
<literal>env -0</literal> and
<filename>/proc/*/environ</filename>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--own-name=NAME</option></term>

View File

@@ -262,6 +262,24 @@ key=v1;v2;
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--env-fd=<replaceable>FD</replaceable></option></term>
<listitem><para>
Read environment variables from the file descriptor
<replaceable>FD</replaceable>, and set them as if
via <option>--env</option>. This can be used to avoid
environment variables and their values becoming visible
to other users.
</para><para>
Each environment variable is in the form
<replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
followed by a zero byte. This is the same format used by
<literal>env -0</literal> and
<filename>/proc/*/environ</filename>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--own-name=NAME</option></term>

View File

@@ -402,6 +402,24 @@ key=v1;v2;
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--env-fd=<replaceable>FD</replaceable></option></term>
<listitem><para>
Read environment variables from the file descriptor
<replaceable>FD</replaceable>, and set them as if
via <option>--env</option>. This can be used to avoid
environment variables and their values becoming visible
to other users.
</para><para>
Each environment variable is in the form
<replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable>
followed by a zero byte. This is the same format used by
<literal>env -0</literal> and
<filename>/proc/*/environ</filename>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--own-name=NAME</option></term>