context: Use the new permission system for shares and features

This gives us conditionals for shares and features. So far we have no
use case for this, but the system already exists, it makes the code
simpler, and when we need this in the future, we don't have to wait for
it to roll out.
This commit is contained in:
Sebastian Wick 2025-12-05 15:34:18 +01:00
parent e0e1b20ecb
commit 6667e1d361
9 changed files with 146 additions and 287 deletions

View File

@ -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;

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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;

View File

@ -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__ */

View File

@ -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);

View File

@ -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.
</para><para>
This option supports conditional permissions.
See <link linkend="conditional-permissions">Conditional Permissions</link>
for details on how to share subsystem access conditionally
based on runtime conditions.
</para></listitem>
</varlistentry>
@ -663,6 +668,11 @@ sockets=!x11;x11;if:x11:!has-wayland;
indicate the absence of that feature, for example
<option>!devel</option> if development and debugging
are not allowed.
</para><para>
This option supports conditional permissions.
See <link linkend="conditional-permissions">Conditional Permissions</link>
for details on how to allow features based
conditionally on runtime conditions.
</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -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"));

View File

@ -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"