diff --git a/app/flatpak-builtins-build.c b/app/flatpak-builtins-build.c index d0aa436e..6b549dd8 100644 --- a/app/flatpak-builtins-build.c +++ b/app/flatpak-builtins-build.c @@ -215,8 +215,10 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError char pid_str[64]; g_autofree char *pid_path = NULL; g_autoptr(GFile) app_id_dir = NULL; + FlatpakContextShares shares; FlatpakContextDevices devices; FlatpakContextSockets sockets; + FlatpakContextFeatures features; context = g_option_context_new (_("DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); @@ -440,6 +442,11 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError flatpak_context_merge (app_context, arg_context); + shares = flatpak_run_compute_allowed_shares (app_context); + devices = flatpak_run_compute_allowed_devices (app_context); + sockets = flatpak_run_compute_allowed_sockets (app_context); + features = flatpak_run_compute_allowed_features (app_context); + minimal_envp = flatpak_run_get_minimal_env (TRUE, FALSE); bwrap = flatpak_bwrap_new (minimal_envp); flatpak_bwrap_add_args (bwrap, flatpak_get_bwrap (), NULL); @@ -452,7 +459,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError if (custom_usr) run_flags |= FLATPAK_RUN_FLAG_WRITABLE_ETC; - run_flags |= flatpak_context_get_run_flags (app_context); + run_flags |= flatpak_context_features_to_run_flags (features); /* Unless manually specified, we disable dbus proxy */ if (!flatpak_context_get_needs_session_bus_proxy (arg_context)) @@ -553,9 +560,6 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError "--bind", flatpak_file_get_path_cached (res_files), extension_point, NULL); - devices = flatpak_run_compute_allowed_devices (app_context); - sockets = flatpak_run_compute_allowed_sockets (app_context); - if (!flatpak_run_add_app_info_args (bwrap, app_files, app_files, NULL, app_extensions, runtime_files, runtime_files, runtime_deploy_data, runtime_extensions, @@ -571,7 +575,8 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError return FALSE; if (!flatpak_run_add_environment_args (bwrap, app_info_path, run_flags, id, - app_context, devices, sockets, + app_context, + shares, devices, sockets, features, app_id_dir, NULL, -1, instance_id, NULL, cancellable, error)) return FALSE; diff --git a/common/flatpak-context-private.h b/common/flatpak-context-private.h index 3c893adc..b8385b5a 100644 --- a/common/flatpak-context-private.h +++ b/common/flatpak-context-private.h @@ -89,12 +89,10 @@ typedef enum { struct FlatpakContext { - FlatpakContextShares shares; - FlatpakContextShares shares_valid; + GHashTable *shares_permissions; GHashTable *socket_permissions; GHashTable *device_permissions; - FlatpakContextFeatures features; - FlatpakContextFeatures features_valid; + GHashTable *features_permissions; GHashTable *env_vars; GHashTable *persistent; GHashTable *filesystems; @@ -148,7 +146,7 @@ char * flatpak_context_devices_to_usb_list (GHashTable *devices, gboolean hidden); void flatpak_context_to_args (FlatpakContext *context, GPtrArray *args); -FlatpakRunFlags flatpak_context_get_run_flags (FlatpakContext *context); +FlatpakRunFlags flatpak_context_features_to_run_flags (FlatpakContextFeatures features); void flatpak_context_add_bus_filters (FlatpakContext *context, const char *app_id, FlatpakBus bus, @@ -164,9 +162,6 @@ void flatpak_context_reset_permissions (FlatpakContext *context); void flatpak_context_reset_non_permissions (FlatpakContext *context); void flatpak_context_make_sandboxed (FlatpakContext *context); -gboolean flatpak_context_allows_features (FlatpakContext *context, - FlatpakContextFeatures features); - FlatpakContext *flatpak_context_load_for_deploy (FlatpakDeploy *deploy, GError **error); @@ -208,9 +203,14 @@ gboolean flatpak_context_get_allowed_exports (FlatpakContext *context, char ***allowed_prefixes_out, gboolean *require_exact_match_out); + +FlatpakContextShares flatpak_context_compute_allowed_shares (FlatpakContext *context, + FlatpakContextConditionEvaluator evaluator); FlatpakContextSockets flatpak_context_compute_allowed_sockets (FlatpakContext *context, FlatpakContextConditionEvaluator evaluator); FlatpakContextDevices flatpak_context_compute_allowed_devices (FlatpakContext *context, FlatpakContextConditionEvaluator evaluator); +FlatpakContextFeatures flatpak_context_compute_allowed_features (FlatpakContext *context, + FlatpakContextConditionEvaluator evaluator); #endif /* __FLATPAK_CONTEXT_H__ */ diff --git a/common/flatpak-context.c b/common/flatpak-context.c index a0b4bf7d..99c8e3e7 100644 --- a/common/flatpak-context.c +++ b/common/flatpak-context.c @@ -161,6 +161,10 @@ flatpak_permission_dup (FlatpakPermission *permission) FlatpakPermission *copy = NULL; copy = flatpak_permission_new (); + + if (!permission) + return copy; + copy->allowed = permission->allowed; copy->reset = permission->reset; @@ -1192,8 +1196,10 @@ flatpak_context_new (void) g_free, (GDestroyNotify) flatpak_usb_query_free); context->hidden_usb_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) flatpak_usb_query_free); + context->shares_permissions = flatpak_permissions_new (); context->socket_permissions = flatpak_permissions_new (); context->device_permissions = flatpak_permissions_new (); + context->features_permissions = flatpak_permissions_new (); return context; } @@ -1210,8 +1216,10 @@ flatpak_context_free (FlatpakContext *context) g_hash_table_destroy (context->generic_policy); g_hash_table_destroy (context->enumerable_usb_devices); g_hash_table_destroy (context->hidden_usb_devices); + g_hash_table_destroy (context->shares_permissions); g_hash_table_destroy (context->device_permissions); g_hash_table_destroy (context->socket_permissions); + g_hash_table_destroy (context->features_permissions); g_slice_free (FlatpakContext, context); } @@ -1229,49 +1237,6 @@ flatpak_context_bitmask_from_string (const char *name, const char **names) return 0; } -static void -flatpak_context_bitmask_to_string (guint32 enabled, - guint32 valid, - const char **names, - GPtrArray *array) -{ - guint32 i; - - for (i = 0; names[i] != NULL; i++) - { - guint32 bitmask = 1 << i; - - if (valid & bitmask) - { - if (enabled & bitmask) - g_ptr_array_add (array, g_strdup (names[i])); - else - g_ptr_array_add (array, g_strdup_printf ("!%s", names[i])); - } - } -} - -static void -flatpak_context_bitmask_to_args (guint32 enabled, guint32 valid, const char **names, - const char *enable_arg, const char *disable_arg, - GPtrArray *args) -{ - guint32 i; - - for (i = 0; names[i] != NULL; i++) - { - guint32 bitmask = 1 << i; - if (valid & bitmask) - { - if (enabled & bitmask) - g_ptr_array_add (args, g_strdup_printf ("%s=%s", enable_arg, names[i])); - else - g_ptr_array_add (args, g_strdup_printf ("%s=%s", disable_arg, names[i])); - } - } -} - - static FlatpakContextShares flatpak_context_share_from_string (const char *string, GError **error) { @@ -1287,30 +1252,6 @@ flatpak_context_share_from_string (const char *string, GError **error) return shares; } -static char ** -flatpak_context_shared_to_string (FlatpakContextShares shares, - FlatpakContextShares valid) -{ - g_autoptr (GPtrArray) array = g_ptr_array_new_with_free_func (g_free); - - flatpak_context_bitmask_to_string (shares, valid, - flatpak_context_shares, - array); - - g_ptr_array_add (array, NULL); - return (char **) g_ptr_array_free (g_steal_pointer (&array), FALSE); -} - -static void -flatpak_context_shared_to_args (FlatpakContext *context, - GPtrArray *args) -{ - flatpak_context_bitmask_to_args (context->shares, context->shares_valid, - flatpak_context_shares, - "--share", "--unshare", - args); -} - static FlatpakPolicy flatpak_policy_from_string (const char *string, GError **error) { @@ -1412,61 +1353,6 @@ flatpak_context_feature_from_string (const char *string, GError **error) return feature; } -static char ** -flatpak_context_features_to_string (FlatpakContextFeatures features, FlatpakContextFeatures valid) -{ - g_autoptr (GPtrArray) array = g_ptr_array_new_with_free_func (g_free); - - flatpak_context_bitmask_to_string (features, valid, - flatpak_context_features, - array); - - g_ptr_array_add (array, NULL); - return (char **) g_ptr_array_free (g_steal_pointer (&array), FALSE); -} - -static void -flatpak_context_features_to_args (FlatpakContext *context, - GPtrArray *args) -{ - flatpak_context_bitmask_to_args (context->features, context->features_valid, - flatpak_context_features, - "--allow", "--disallow", - args); -} - -static void -flatpak_context_add_shares (FlatpakContext *context, - FlatpakContextShares shares) -{ - context->shares_valid |= shares; - context->shares |= shares; -} - -static void -flatpak_context_remove_shares (FlatpakContext *context, - FlatpakContextShares shares) -{ - context->shares_valid |= shares; - context->shares &= ~shares; -} - -static void -flatpak_context_add_features (FlatpakContext *context, - FlatpakContextFeatures features) -{ - context->features_valid |= features; - context->features |= features; -} - -static void -flatpak_context_remove_features (FlatpakContext *context, - FlatpakContextFeatures features) -{ - context->features_valid |= features; - context->features &= ~features; -} - static void flatpak_context_set_env_var (FlatpakContext *context, const char *name, @@ -2097,17 +1983,14 @@ flatpak_context_merge (FlatpakContext *context, GHashTableIter iter; gpointer key, value; - context->shares &= ~other->shares_valid; - context->shares |= other->shares; - context->shares_valid |= other->shares_valid; - context->features &= ~other->features_valid; - context->features |= other->features; - context->features_valid |= other->features_valid; - + flatpak_permissions_merge (context->shares_permissions, + other->shares_permissions); flatpak_permissions_merge (context->socket_permissions, other->socket_permissions); flatpak_permissions_merge (context->device_permissions, other->device_permissions); + flatpak_permissions_merge (context->features_permissions, + other->features_permissions); g_hash_table_iter_init (&iter, other->env_vars); while (g_hash_table_iter_next (&iter, &key, &value)) @@ -2173,7 +2056,7 @@ option_share_cb (const gchar *option_name, if (share == 0) return FALSE; - flatpak_context_add_shares (context, share); + flatpak_permissions_set_allowed (context->shares_permissions, value); return TRUE; } @@ -2191,7 +2074,7 @@ option_unshare_cb (const gchar *option_name, if (share == 0) return FALSE; - flatpak_context_remove_shares (context, share); + flatpak_permissions_set_not_allowed (context->shares_permissions, value); return TRUE; } @@ -2374,7 +2257,7 @@ option_allow_cb (const gchar *option_name, if (feature == 0) return FALSE; - flatpak_context_add_features (context, feature); + flatpak_permissions_set_allowed (context->features_permissions, value); return TRUE; } @@ -2392,7 +2275,7 @@ option_disallow_cb (const gchar *option_name, if (feature == 0) return FALSE; - flatpak_context_remove_features (context, feature); + flatpak_permissions_set_not_allowed (context->features_permissions, value); return TRUE; } @@ -2862,52 +2745,6 @@ parse_negated (const char *option, gboolean *negated) return option; } -static void -flatpak_context_load_share (FlatpakContext *context, - const char *share_str) -{ - FlatpakContextShares share; - gboolean remove; - - share = - flatpak_context_share_from_string (parse_negated (share_str, &remove), - NULL); - - if (share == 0) - { - g_info ("Unknown share type %s", share_str); - return; - } - - if (remove) - flatpak_context_remove_shares (context, share); - else - flatpak_context_add_shares (context, share); -} - -static void -flatpak_context_load_feature (FlatpakContext *context, - const char *feature_str) -{ - FlatpakContextFeatures feature; - gboolean remove; - - feature = - flatpak_context_feature_from_string (parse_negated (feature_str, &remove), - NULL); - - if (feature == 0) - { - g_info ("Unknown feature type %s", feature_str); - return; - } - - if (remove) - flatpak_context_remove_features (context, feature); - else - flatpak_context_add_features (context, feature); -} - /* * Merge the FLATPAK_METADATA_GROUP_CONTEXT, * FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY, @@ -2933,8 +2770,8 @@ flatpak_context_load_metadata (FlatpakContext *context, if (shares == NULL) return FALSE; - for (i = 0; shares[i] != NULL; i++) - flatpak_context_load_share (context, shares[i]); + if (!flatpak_permissions_from_strv (context->shares_permissions, (const char **)shares, error)) + return FALSE; } if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_SOCKETS, NULL)) @@ -2967,8 +2804,8 @@ flatpak_context_load_metadata (FlatpakContext *context, if (features == NULL) return FALSE; - for (i = 0; features[i] != NULL; i++) - flatpak_context_load_feature (context, features[i]); + if (!flatpak_permissions_from_strv (context->features_permissions, (const char **)features, error)) + return FALSE; } if (g_key_file_has_key (metakey, FLATPAK_METADATA_GROUP_CONTEXT, FLATPAK_METADATA_KEY_FILESYSTEMS, NULL)) @@ -3221,34 +3058,14 @@ flatpak_context_save_metadata (FlatpakContext *context, g_autoptr(GPtrArray) unset_env = NULL; GHashTableIter iter; gpointer key, value; - FlatpakContextShares shares_mask = context->shares; - FlatpakContextShares shares_valid = context->shares_valid; - FlatpakContextFeatures features_mask = context->features; - FlatpakContextFeatures features_valid = context->features_valid; g_auto(GStrv) groups = NULL; int i; - if (flatten) - { - /* A flattened format means we don't expect this to be merged on top of - another context. In that case we never need to negate any flags. - We calculate this by removing the zero parts of the mask from the valid set. - */ - /* First we make sure only the valid parts of the mask are set, in case we - got some leftover */ - shares_mask &= shares_valid; - features_mask &= features_valid; - - /* Then just set the valid set to be the mask set */ - shares_valid = shares_mask; - features_valid = features_mask; - } - - shared = flatpak_context_shared_to_string (shares_mask, shares_valid); + shared = flatpak_permissions_to_strv (context->shares_permissions, flatten); g_autoptr(GHashTable) socket_permissions = flatpak_decanonicalize_x11_permissions (context->socket_permissions); sockets = flatpak_permissions_to_strv (socket_permissions, flatten); devices = flatpak_permissions_to_strv (context->device_permissions, flatten); - features = flatpak_context_features_to_string (features_mask, features_valid); + features = flatpak_permissions_to_strv (context->features_permissions, flatten); if (shared[0] != NULL) { @@ -3503,12 +3320,6 @@ flatpak_context_get_needs_system_bus_proxy (FlatpakContext *context) return g_hash_table_size (context->system_bus_policy) > 0; } -static gboolean -adds_flags (guint32 old_flags, guint32 new_flags) -{ - return (new_flags & ~old_flags) != 0; -} - static gboolean adds_bus_policy (GHashTable *old, GHashTable *new) { @@ -3608,18 +3419,15 @@ gboolean flatpak_context_adds_permissions (FlatpakContext *old, FlatpakContext *new) { + g_autoptr(GHashTable) old_features_permissions = NULL; g_autoptr(GHashTable) old_socket_permissions = NULL; - guint32 harmless_features; + old_features_permissions = flatpak_permissions_dup (old->features_permissions); /* We allow upgrade to multiarch, that is really not a huge problem. * Similarly, having sensible semantics for /dev/shm is * not a security concern. */ - harmless_features = (FLATPAK_CONTEXT_FEATURE_MULTIARCH | - FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM); - - if (adds_flags (old->shares & old->shares_valid, - new->shares & new->shares_valid)) - return TRUE; + flatpak_permissions_set_allowed (old_features_permissions, "multiarch"); + flatpak_permissions_set_allowed (old_features_permissions, "per-app-dev-shm"); old_socket_permissions = flatpak_permissions_dup (old->socket_permissions); /* If we used to allow X11, also allow new fallback X11, @@ -3627,6 +3435,10 @@ flatpak_context_adds_permissions (FlatpakContext *old, if (flatpak_permissions_allows_unconditionally (old_socket_permissions, "x11")) flatpak_permissions_set_allowed (old_socket_permissions, "fallback-x11"); + if (flatpak_permissions_adds_permissions (old->shares_permissions, + new->shares_permissions)) + return TRUE; + if (flatpak_permissions_adds_permissions (old_socket_permissions, new->socket_permissions)) return TRUE; @@ -3635,9 +3447,9 @@ flatpak_context_adds_permissions (FlatpakContext *old, new->device_permissions)) return TRUE; - if (adds_flags ((old->features & old->features_valid) | harmless_features, - new->features & new->features_valid)) - return TRUE; + if (flatpak_permissions_adds_permissions (old_features_permissions, + new->features_permissions)) + return TRUE; if (adds_bus_policy (old->session_bus_policy, new->session_bus_policy)) return TRUE; @@ -3660,13 +3472,6 @@ flatpak_context_adds_permissions (FlatpakContext *old, return FALSE; } -gboolean -flatpak_context_allows_features (FlatpakContext *context, - FlatpakContextFeatures features) -{ - return (context->features & features) == features; -} - char * flatpak_context_devices_to_usb_list (GHashTable *devices, gboolean hidden) @@ -3695,8 +3500,10 @@ flatpak_context_to_args (FlatpakContext *context, gpointer key, value; char *usb_list = NULL; - flatpak_context_shared_to_args (context, args); - flatpak_context_features_to_args (context, args); + flatpak_permissions_to_args (context->features_permissions, + "allow", "disallow", args); + flatpak_permissions_to_args (context->shares_permissions, + "share", "unshare", args); flatpak_permissions_to_args (context->device_permissions, "device", "nodevice", args); flatpak_permissions_to_args (context->socket_permissions, @@ -3839,14 +3646,10 @@ flatpak_context_reset_non_permissions (FlatpakContext *context) void flatpak_context_reset_permissions (FlatpakContext *context) { - context->shares_valid = 0; - context->features_valid = 0; - - context->shares = 0; - context->features = 0; - + g_hash_table_remove_all (context->shares_permissions); g_hash_table_remove_all (context->socket_permissions); g_hash_table_remove_all (context->device_permissions); + g_hash_table_remove_all (context->features_permissions); g_hash_table_remove_all (context->persistent); g_hash_table_remove_all (context->filesystems); g_hash_table_remove_all (context->session_bus_policy); @@ -3861,14 +3664,20 @@ flatpak_context_make_sandboxed (FlatpakContext *context) /* We drop almost everything from the app permission, except * multiarch which is inherited, to make sure app code keeps * running. */ - context->shares_valid &= 0; - context->features_valid &= FLATPAK_CONTEXT_FEATURE_MULTIARCH; - - context->shares &= context->shares_valid; - context->features &= context->features_valid; + FlatpakPermission *multiarch = + g_hash_table_lookup (context->features_permissions, "multiarch"); + g_hash_table_remove_all (context->shares_permissions); g_hash_table_remove_all (context->socket_permissions); g_hash_table_remove_all (context->device_permissions); + g_hash_table_remove_all (context->features_permissions); + + if (multiarch) + { + g_hash_table_insert (context->features_permissions, + g_strdup ("multiarch"), + flatpak_permission_dup (multiarch)); + } g_hash_table_remove_all (context->persistent); g_hash_table_remove_all (context->filesystems); @@ -4214,20 +4023,20 @@ flatpak_context_get_exports (FlatpakContext *context, } FlatpakRunFlags -flatpak_context_get_run_flags (FlatpakContext *context) +flatpak_context_features_to_run_flags (FlatpakContextFeatures features) { FlatpakRunFlags flags = 0; - if (flatpak_context_allows_features (context, FLATPAK_CONTEXT_FEATURE_DEVEL)) + if (features & FLATPAK_CONTEXT_FEATURE_DEVEL) flags |= FLATPAK_RUN_FLAG_DEVEL; - if (flatpak_context_allows_features (context, FLATPAK_CONTEXT_FEATURE_MULTIARCH)) + if (features & FLATPAK_CONTEXT_FEATURE_MULTIARCH) flags |= FLATPAK_RUN_FLAG_MULTIARCH; - if (flatpak_context_allows_features (context, FLATPAK_CONTEXT_FEATURE_BLUETOOTH)) + if (features & FLATPAK_CONTEXT_FEATURE_BLUETOOTH) flags |= FLATPAK_RUN_FLAG_BLUETOOTH; - if (flatpak_context_allows_features (context, FLATPAK_CONTEXT_FEATURE_CANBUS)) + if (features & FLATPAK_CONTEXT_FEATURE_CANBUS) flags |= FLATPAK_RUN_FLAG_CANBUS; return flags; @@ -4634,6 +4443,15 @@ flatpak_context_dump (FlatpakContext *context, } } +FlatpakContextShares +flatpak_context_compute_allowed_shares (FlatpakContext *context, + FlatpakContextConditionEvaluator evaluator) +{ + return flatpak_permissions_compute_allowed (context->shares_permissions, + flatpak_context_shares, + evaluator); +} + FlatpakContextSockets flatpak_context_compute_allowed_sockets (FlatpakContext *context, FlatpakContextConditionEvaluator evaluator) @@ -4651,3 +4469,13 @@ flatpak_context_compute_allowed_devices (FlatpakContext *conte flatpak_context_devices, evaluator); } + + +FlatpakContextFeatures +flatpak_context_compute_allowed_features (FlatpakContext *context, + FlatpakContextConditionEvaluator evaluator) +{ + return flatpak_permissions_compute_allowed (context->features_permissions, + flatpak_context_features, + evaluator); +} diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index f1e29de5..c15e993d 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -9321,7 +9321,7 @@ apply_extra_data (FlatpakDir *self, app_context = flatpak_context_new (); if (!flatpak_run_add_environment_args (bwrap, NULL, run_flags, id, - app_context, 0, 0, + app_context, 0, 0, 0, 0, NULL, NULL, -1, NULL, NULL, cancellable, error)) return FALSE; diff --git a/common/flatpak-run-private.h b/common/flatpak-run-private.h index 2dc08acf..d46996de 100644 --- a/common/flatpak-run-private.h +++ b/common/flatpak-run-private.h @@ -51,8 +51,10 @@ gboolean flatpak_run_add_environment_args (FlatpakBwrap *bwrap, FlatpakRunFlags flags, const char *app_id, FlatpakContext *context, + FlatpakContextShares shares, FlatpakContextDevices devices, FlatpakContextSockets sockets, + FlatpakContextFeatures features, GFile *app_id_dir, GPtrArray *previous_app_id_dirs, int per_app_dir_lock_fd, @@ -125,8 +127,10 @@ gboolean flatpak_run_app (FlatpakDecomposed *app_ref, GCancellable *cancellable, GError **error); -FlatpakContextDevices flatpak_run_compute_allowed_devices (FlatpakContext *context); +FlatpakContextShares flatpak_run_compute_allowed_shares (FlatpakContext *context); +FlatpakContextDevices flatpak_run_compute_allowed_devices (FlatpakContext *context); FlatpakContextSockets flatpak_run_compute_allowed_sockets (FlatpakContext *context); +FlatpakContextFeatures flatpak_run_compute_allowed_features (FlatpakContext *context); #endif /* __FLATPAK_RUN_H__ */ diff --git a/common/flatpak-run.c b/common/flatpak-run.c index 15f59065..6c319231 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -288,8 +288,10 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, FlatpakRunFlags flags, const char *app_id, FlatpakContext *context, + FlatpakContextShares shares, FlatpakContextDevices devices, FlatpakContextSockets sockets, + FlatpakContextFeatures features, GFile *app_id_dir, GPtrArray *previous_app_id_dirs, int per_app_dir_lock_fd, @@ -305,13 +307,13 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, gboolean home_access = FALSE; gboolean sandboxed = (flags & FLATPAK_RUN_FLAG_SANDBOX) != 0; - if ((context->shares & FLATPAK_CONTEXT_SHARED_IPC) == 0) + if ((shares & FLATPAK_CONTEXT_SHARED_IPC) == 0) { g_info ("Disallowing ipc access"); flatpak_bwrap_add_args (bwrap, "--unshare-ipc", NULL); } - if ((context->shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0) + if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0) { g_info ("Disallowing network access"); flatpak_bwrap_add_args (bwrap, "--unshare-net", NULL); @@ -331,7 +333,7 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, * shared /dev. The host and all sandboxes and subsandboxes * all share /dev/shm */ } - else if ((context->features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) + else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) && per_app_dir_lock_fd >= 0) { g_autofree char *shared_dev_shm = NULL; @@ -374,7 +376,7 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, "--bind", "/run/shm", "/run/shm", NULL); } - else if ((context->features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) + else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) && per_app_dir_lock_fd >= 0) { g_autofree char *shared_dev_shm = NULL; @@ -477,7 +479,7 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, if (real_dev_shm != NULL) flatpak_bwrap_add_args (bwrap, "--bind", real_dev_shm, "/dev/shm", NULL); } - else if ((context->features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) + else if ((features & FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM) && per_app_dir_lock_fd >= 0) { g_autofree char *shared_dev_shm = NULL; @@ -530,7 +532,7 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap, flatpak_context_append_bwrap_filesystem (context, bwrap, app_id, app_id_dir, exports, xdg_dirs_conf, home_access); - flatpak_run_add_socket_args_environment (bwrap, context->shares, sockets, app_id, instance_id); + flatpak_run_add_socket_args_environment (bwrap, shares, sockets, app_id, instance_id); flatpak_run_add_session_dbus_args (bwrap, proxy_arg_bwrap, sockets, context, flags, app_id); flatpak_run_add_system_dbus_args (bwrap, proxy_arg_bwrap, sockets, context, flags); flatpak_run_add_a11y_dbus_args (bwrap, proxy_arg_bwrap, context, flags, app_id); @@ -2947,6 +2949,13 @@ open_namespace_fd_if_needed (const char *path, return -1; } +FlatpakContextShares +flatpak_run_compute_allowed_shares (FlatpakContext *context) +{ + return flatpak_context_compute_allowed_shares (context, + flatpak_run_evaluate_conditions); +} + FlatpakContextDevices flatpak_run_compute_allowed_devices (FlatpakContext *context) { @@ -2961,6 +2970,13 @@ flatpak_run_compute_allowed_sockets (FlatpakContext *context) flatpak_run_evaluate_conditions); } +FlatpakContextFeatures +flatpak_run_compute_allowed_features (FlatpakContext *context) +{ + return flatpak_context_compute_allowed_features (context, + flatpak_run_evaluate_conditions); +} + gboolean flatpak_run_app (FlatpakDecomposed *app_ref, FlatpakDeploy *app_deploy, @@ -3032,8 +3048,10 @@ flatpak_run_app (FlatpakDecomposed *app_ref, const char *app_target_path = "/app"; const char *runtime_target_path = "/usr"; struct stat s; + FlatpakContextShares shares; FlatpakContextDevices devices; FlatpakContextSockets sockets; + FlatpakContextFeatures features; g_assert (run_environ != NULL); @@ -3164,8 +3182,10 @@ flatpak_run_app (FlatpakDecomposed *app_ref, flatpak_context_dump (app_context, "Final context"); + shares = flatpak_run_compute_allowed_shares (app_context); devices = flatpak_run_compute_allowed_devices (app_context); sockets = flatpak_run_compute_allowed_sockets (app_context); + features = flatpak_run_compute_allowed_features (app_context); original_runtime_files = flatpak_deploy_get_files (runtime_deploy); @@ -3441,7 +3461,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref, flatpak_bwrap_add_fd (bwrap, ld_so_fd); } - flags |= flatpak_context_get_run_flags (app_context); + flags |= flatpak_context_features_to_run_flags (features); if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, app_arch, flags, error)) return FALSE; @@ -3504,7 +3524,8 @@ flatpak_run_app (FlatpakDecomposed *app_ref, add_document_portal_args (bwrap, app_id, &doc_mount_path); if (!flatpak_run_add_environment_args (bwrap, app_info_path, flags, - app_id, app_context, devices, sockets, + app_id, app_context, + shares, devices, sockets, features, app_id_dir, previous_app_id_dirs, per_app_dir_lock_fd, instance_id, &exports, cancellable, error)) @@ -3520,7 +3541,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref, NULL); } - flatpak_run_add_socket_args_late (bwrap, app_context->shares); + flatpak_run_add_socket_args_late (bwrap, shares); add_font_path_args (bwrap); add_icon_path_args (bwrap); diff --git a/doc/flatpak-metadata.xml b/doc/flatpak-metadata.xml index 6a8f5e67..92bb02b1 100644 --- a/doc/flatpak-metadata.xml +++ b/doc/flatpak-metadata.xml @@ -244,6 +244,11 @@ sockets=!x11;x11;if:x11:!has-wayland; List of subsystems to share with the host system. Possible subsystems: network, ipc. Available since 0.3. + + This option supports conditional permissions. + See Conditional Permissions + for details on how to share subsystem access conditionally + based on runtime conditions. @@ -663,6 +668,11 @@ sockets=!x11;x11;if:x11:!has-wayland; indicate the absence of that feature, for example if development and debugging are not allowed. + + This option supports conditional permissions. + See Conditional Permissions + for details on how to allow features based + conditionally on runtime conditions. diff --git a/tests/test-exports.c b/tests/test-exports.c index a93bfe05..851be370 100644 --- a/tests/test-exports.c +++ b/tests/test-exports.c @@ -177,13 +177,10 @@ test_empty_context (void) g_assert_cmpuint (g_hash_table_size (context->session_bus_policy), ==, 0); g_assert_cmpuint (g_hash_table_size (context->system_bus_policy), ==, 0); g_assert_cmpuint (g_hash_table_size (context->generic_policy), ==, 0); + g_assert_cmpuint (g_hash_table_size (context->shares_permissions), ==, 0); g_assert_cmpuint (g_hash_table_size (context->socket_permissions), ==, 0); g_assert_cmpuint (g_hash_table_size (context->device_permissions), ==, 0); - g_assert_cmpuint (context->shares, ==, 0); - g_assert_cmpuint (context->shares_valid, ==, 0); - g_assert_cmpuint (context->features, ==, 0); - g_assert_cmpuint (context->features_valid, ==, 0); - g_assert_cmpuint (flatpak_context_get_run_flags (context), ==, 0); + g_assert_cmpuint (g_hash_table_size (context->features_permissions), ==, 0); exports = flatpak_context_get_exports (context, "com.example.App"); g_assert_nonnull (exports); @@ -266,10 +263,10 @@ test_full_context (void) flatpak_context_load_metadata (context, keyfile, &error); g_assert_no_error (error); - g_assert_cmpuint (context->shares, ==, + FlatpakContextShares shares = flatpak_context_compute_allowed_shares (context, NULL); + g_assert_cmpuint (shares, ==, (FLATPAK_CONTEXT_SHARED_NETWORK | FLATPAK_CONTEXT_SHARED_IPC)); - g_assert_cmpuint (context->shares_valid, ==, context->shares); FlatpakContextDevices devices = flatpak_context_compute_allowed_devices (context, NULL); g_assert_cmpuint (devices, ==, (FLATPAK_CONTEXT_DEVICE_DRI | @@ -286,19 +283,13 @@ test_full_context (void) FLATPAK_CONTEXT_SOCKET_SSH_AUTH | FLATPAK_CONTEXT_SOCKET_PCSC | FLATPAK_CONTEXT_SOCKET_CUPS)); - g_assert_cmpuint (context->features, ==, + FlatpakContextFeatures features = flatpak_context_compute_allowed_features (context, NULL); + g_assert_cmpuint (features, ==, (FLATPAK_CONTEXT_FEATURE_DEVEL | FLATPAK_CONTEXT_FEATURE_MULTIARCH | FLATPAK_CONTEXT_FEATURE_BLUETOOTH | FLATPAK_CONTEXT_FEATURE_CANBUS | FLATPAK_CONTEXT_FEATURE_PER_APP_DEV_SHM)); - g_assert_cmpuint (context->features_valid, ==, context->features); - - g_assert_cmpuint (flatpak_context_get_run_flags (context), ==, - (FLATPAK_RUN_FLAG_DEVEL | - FLATPAK_RUN_FLAG_MULTIARCH | - FLATPAK_RUN_FLAG_BLUETOOTH | - FLATPAK_RUN_FLAG_CANBUS)); g_assert_cmpuint (g_hash_table_size (context->env_vars), ==, 3); g_assert_true (g_hash_table_contains (context->env_vars, "LD_AUDIT")); diff --git a/tests/test-override.sh b/tests/test-override.sh index 8c9c719b..3de3ddf0 100755 --- a/tests/test-override.sh +++ b/tests/test-override.sh @@ -61,7 +61,7 @@ ${FLATPAK} override --user --unshare=ipc org.test.Hello ${FLATPAK} override --user --show org.test.Hello > override assert_file_has_content override "^\[Context\]$" -assert_file_has_content override "^shared=network;!ipc;$" +assert_file_has_content override "^shared=!ipc;network;$" ok "override --share" @@ -85,7 +85,7 @@ ${FLATPAK} override --user --disallow=bluetooth org.test.Hello ${FLATPAK} override --user --show org.test.Hello > override assert_file_has_content override "^\[Context\]$" -assert_file_has_content override "^features=multiarch;!bluetooth;$" +assert_file_has_content override "^features=!bluetooth;multiarch;$" ok "override --allow"