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"