Add a --forbid option to run

This allows to restrict the access that the app gets out of
the sandbox. We allow an access if the app requests it (in its
metadata) and the user doesn't forbid it (with this option).
tingping/wmclass
Matthias Clasen 2015-02-06 17:33:09 +01:00
parent 0abf45b01b
commit c313cafbae
3 changed files with 63 additions and 12 deletions

View File

@ -28,12 +28,12 @@ _xdg-app() {
[LIST_REMOTES]='--show-urls'
[REPO_CONTENTS]='--show-details --runtimes --apps --update'
[UNINSTALL]='--keep-ref'
[RUN]='--command --branch --devel'
[RUN]='--command --branch --devel --forbid'
[BUILD_INIT]='--arch --var'
[BUILD]='--runtime --network --x11'
[BUILD_FINISH]='--command --allow'
[BUILD_EXPORT]='--subject --body'
[ARG]='--arch --command --branch --var --allow --subject --body'
[ARG]='--arch --command --branch --var --allow --forbid --subject --body'
)
if __contains_word "--user" ${COMP_WORDS[*]}; then
@ -53,7 +53,7 @@ _xdg-app() {
--var)
comps=$(xdg-app $mode list-runtimes)
;;
--allow)
--allow|--forbid)
comps='x11 wayland ipc pulseaudio system-dbus session-dbus network host-fs homedir'
;;
--branch|--subject|--body)

View File

@ -51,6 +51,12 @@
directory at <filename>/var</filename>, whose content is preserved between
application runs. The application itself is mounted at <filename>/self</filename>.
</para>
<para>
The details of the sandboxed environment are controlled by the application
metadata and the --forbid option that are passed to the run command: Access
is allowed if the application requested it in its metadata file and the
user hasn;t forbidden it.
</para>
</refsect1>
@ -110,6 +116,17 @@
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--forbid=KEY</option></term>
<listitem><para>
Disallow access to the named facility. KEY must
be one of: x11, wayland, ipc, pulseaudio, system-dbus,
session-dbus, network, host-fs, homedir.
This option can be used multiple times.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<term><option>--verbose</option></term>

View File

@ -17,6 +17,7 @@ static char *opt_branch;
static char *opt_command;
static gboolean opt_devel;
static char *opt_runtime;
static char **opt_forbid;
static GOptionEntry options[] = {
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to use", "ARCH" },
@ -24,6 +25,7 @@ static GOptionEntry options[] = {
{ "branch", 0, 0, G_OPTION_ARG_STRING, &opt_branch, "Branch to use", "BRANCH" },
{ "devel", 'd', 0, G_OPTION_ARG_NONE, &opt_devel, "Use development runtime", NULL },
{ "runtime", 0, 0, G_OPTION_ARG_STRING, &opt_runtime, "Runtime to use", "RUNTIME" },
{ "forbid", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_forbid, "Environment options to set to false", "KEY" },
{ NULL }
};
@ -259,6 +261,12 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
const char *command = "/bin/sh";
int i;
int rest_argv_start, rest_argc;
const char *environment_keys[] = {
"x11", "wayland", "ipc", "pulseaudio", "system-dbus", "session-dbus",
"network", "host-fs", "homedir", NULL
};
const char *no_opts[1] = { NULL };
const char **forbid;
context = g_option_context_new ("APP [args...] - Run an app");
@ -399,33 +407,59 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
}
}
if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL))
if (opt_forbid)
forbid = (const char **)opt_forbid;
else
forbid = no_opts;
for (i = 0; forbid[i]; i++)
{
const char *key;
key = forbid[i];
if (!g_strv_contains (environment_keys, key))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown Environment key %s", key);
goto out;
}
}
if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL) &&
!g_strv_contains (forbid, "ipc"))
g_ptr_array_add (argv_array, g_strdup ("-i"));
if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL) &&
!g_strv_contains (forbid, "host-fs"))
g_ptr_array_add (argv_array, g_strdup ("-f"));
if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL) &&
!g_strv_contains (forbid, "homedir"))
g_ptr_array_add (argv_array, g_strdup ("-H"));
if (g_key_file_get_boolean (metakey, "Environment", "network", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "network", NULL) &&
!g_strv_contains (forbid, "network"))
g_ptr_array_add (argv_array, g_strdup ("-n"));
if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL) &&
!g_strv_contains (forbid, "x11"))
xdg_app_run_add_x11_args (argv_array);
else
xdg_app_run_add_no_x11_args (argv_array);
if (g_key_file_get_boolean (metakey, "Environment", "wayland", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "wayland", NULL) &&
!g_strv_contains (forbid, "wayland"))
xdg_app_run_add_wayland_args (argv_array);
if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL) &&
!g_strv_contains (forbid, "pulseaudio"))
xdg_app_run_add_pulseaudio_args (argv_array);
if (g_key_file_get_boolean (metakey, "Environment", "system-dbus", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "system-dbus", NULL) &&
!g_strv_contains (forbid, "system-dbus"));
xdg_app_run_add_system_dbus_args (argv_array);
if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL))
if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL) &&
!g_strv_contains (forbid, "session_dbus"))
xdg_app_run_add_session_dbus_args (argv_array);
g_ptr_array_add (argv_array, g_strdup ("-a"));