diff --git a/completion/xdg-app b/completion/xdg-app index 1d924cd9..c8b0561c 100755 --- a/completion/xdg-app +++ b/completion/xdg-app @@ -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) diff --git a/doc/xdg-app-run.xml b/doc/xdg-app-run.xml index 6d3918a2..8ef3db6e 100644 --- a/doc/xdg-app-run.xml +++ b/doc/xdg-app-run.xml @@ -51,6 +51,12 @@ directory at /var, whose content is preserved between application runs. The application itself is mounted at /self. + + 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. + @@ -110,6 +116,17 @@ + + + + + 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. + + + diff --git a/xdg-app-builtins-run.c b/xdg-app-builtins-run.c index 6433254a..383720b5 100644 --- a/xdg-app-builtins-run.c +++ b/xdg-app-builtins-run.c @@ -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,34 +407,89 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** } } - if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL)) - g_ptr_array_add (argv_array, g_strdup ("-i")); - - if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL)) - g_ptr_array_add (argv_array, g_strdup ("-f")); - - if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL)) - g_ptr_array_add (argv_array, g_strdup ("-H")); - - if (g_key_file_get_boolean (metakey, "Environment", "network", NULL)) - g_ptr_array_add (argv_array, g_strdup ("-n")); - - if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL)) - xdg_app_run_add_x11_args (argv_array); + if (opt_forbid) + forbid = (const char **)opt_forbid; else - xdg_app_run_add_no_x11_args (argv_array); + forbid = no_opts; - if (g_key_file_get_boolean (metakey, "Environment", "wayland", NULL)) - xdg_app_run_add_wayland_args (argv_array); + for (i = 0; forbid[i]; i++) + { + const char *key; - if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL)) - xdg_app_run_add_pulseaudio_args (argv_array); + 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", "system-dbus", NULL)) - xdg_app_run_add_system_dbus_args (argv_array); + if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL) && + !g_strv_contains (forbid, "ipc")) + { + g_debug ("Allowing ipc access"); + g_ptr_array_add (argv_array, g_strdup ("-i")); + } - if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL)) - xdg_app_run_add_session_dbus_args (argv_array); + if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL) && + !g_strv_contains (forbid, "host-fs")) + { + g_debug ("Allowing host-fs access"); + g_ptr_array_add (argv_array, g_strdup ("-f")); + } + + if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL) && + !g_strv_contains (forbid, "homedir")) + { + g_debug ("Allowing homedir access"); + g_ptr_array_add (argv_array, g_strdup ("-H")); + } + + if (g_key_file_get_boolean (metakey, "Environment", "network", NULL) && + !g_strv_contains (forbid, "network")) + { + g_debug ("Allowing network access"); + g_ptr_array_add (argv_array, g_strdup ("-n")); + } + + if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL) && + !g_strv_contains (forbid, "x11")) + { + g_debug ("Allowing x11 access"); + 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) && + !g_strv_contains (forbid, "wayland")) + { + g_debug ("Allowing wayland access"); + xdg_app_run_add_wayland_args (argv_array); + } + + if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL) && + !g_strv_contains (forbid, "pulseaudio")) + { + g_debug ("Allowing pulseaudio access"); + xdg_app_run_add_pulseaudio_args (argv_array); + } + + if (g_key_file_get_boolean (metakey, "Environment", "system-dbus", NULL) && + !g_strv_contains (forbid, "system-dbus")); + { + g_debug ("Allowing system-dbus access"); + xdg_app_run_add_system_dbus_args (argv_array); + } + + if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL) && + !g_strv_contains (forbid, "session-dbus")) + { + g_debug ("Allowing session-dbus access"); + xdg_app_run_add_session_dbus_args (argv_array); + } g_ptr_array_add (argv_array, g_strdup ("-a")); g_ptr_array_add (argv_array, g_file_get_path (app_files));