portal: Add the ability to unset environment variables

This is really just syntactic sugar for running `env -u VAR ... COMMAND`,
but env(1) is inconvenient when the form of the COMMAND is not known:
if the COMMAND might contain an equals sign, you end up having to run
`env -u VAR sh -c 'exec "$@"' sh COMMAND`. Let's make this simpler.

This follows up from GHSA-4ppf-fxf6-vxg2 to fix an issue that I noticed
while resolving that vulnerability, but is not required for fixing the
vulnerability.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie
2021-01-12 13:42:05 +00:00
committed by Alexander Larsson
parent 4108e02245
commit c4a58d5822
2 changed files with 34 additions and 0 deletions

View File

@@ -223,6 +223,14 @@
This was added in version 3 of this interface (available from flatpak 1.6.0 and later).
</para></listitem>
</varlistentry>
<varlistentry>
<term>unset-env as</term>
<listitem><para>
A list of environment variables to unset (remove from the environment).
</para><para>
This was added in version 5 of this interface (available from flatpak 1.10.0 and later).
</para></listitem>
</varlistentry>
</variablelist>
-->

View File

@@ -775,6 +775,7 @@ handle_spawn (PortalFlatpak *object,
g_auto(GStrv) shares = NULL;
g_auto(GStrv) sockets = NULL;
g_auto(GStrv) devices = NULL;
g_auto(GStrv) unset_env = NULL;
g_auto(GStrv) sandbox_expose = NULL;
g_auto(GStrv) sandbox_expose_ro = NULL;
g_autoptr(GVariant) sandbox_expose_fd = NULL;
@@ -874,6 +875,7 @@ handle_spawn (PortalFlatpak *object,
g_variant_lookup (arg_options, "sandbox-flags", "u", &sandbox_flags);
sandbox_expose_fd = g_variant_lookup_value (arg_options, "sandbox-expose-fd", G_VARIANT_TYPE ("ah"));
sandbox_expose_fd_ro = g_variant_lookup_value (arg_options, "sandbox-expose-fd-ro", G_VARIANT_TYPE ("ah"));
g_variant_lookup (arg_options, "unset-env", "^as", &unset_env);
if ((sandbox_flags & ~FLATPAK_SPAWN_SANDBOX_FLAGS_ALL) != 0)
{
@@ -1126,6 +1128,30 @@ handle_spawn (PortalFlatpak *object,
child_setup_data.env_fd));
}
for (i = 0; unset_env != NULL && unset_env[i] != NULL; i++)
{
const char *var = unset_env[i];
if (var[0] == '\0')
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Environment variable cannot have empty name");
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
if (strchr (var, '=') != NULL)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Environment variable name cannot contain '='");
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
g_ptr_array_add (flatpak_argv,
g_strdup_printf ("--unset-env=%s", var));
}
expose_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS) != 0;
share_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_SHARE_PIDS) != 0;