Skip to content
Permalink
Browse files Browse the repository at this point in the history
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: GHSA-4ppf-fxf6-vxg2
  • Loading branch information
smcv authored and alexlarsson committed Jan 14, 2021
1 parent 8212498 commit 6e5ae7a
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
60 changes: 60 additions & 0 deletions common/flatpak-context.c
Expand Up @@ -1119,6 +1119,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)

This comment has been minimized.

Copy link
@mwleeds

mwleeds Jan 14, 2021

Collaborator

Why is this conditional needed?

close (fd);

return TRUE;
}

static gboolean
option_own_name_cb (const gchar *option_name,
const gchar *value,
Expand Down Expand Up @@ -1316,6 +1375,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") },
Expand Down
18 changes: 18 additions & 0 deletions doc/flatpak-build-finish.xml
Expand Up @@ -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>

Expand Down
18 changes: 18 additions & 0 deletions doc/flatpak-build.xml
Expand Up @@ -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>

Expand Down
18 changes: 18 additions & 0 deletions doc/flatpak-override.xml
Expand Up @@ -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>

Expand Down
18 changes: 18 additions & 0 deletions doc/flatpak-run.xml
Expand Up @@ -409,6 +409,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>

Expand Down

0 comments on commit 6e5ae7a

Please sign in to comment.