summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2021-10-19 11:48:00 +0200
committerAlexander Larsson <alexl@redhat.com>2022-01-12 14:54:40 +0100
commit307ee18dd62f65c1319594501d01bbdb10f88ab8 (patch)
tree9836bdfce536b3d32046040bbe07f25d418a33c9
parentce0bb56c6fc256ee0aee5407924243f0c0f14559 (diff)
downloadflatpak-307ee18dd62f65c1319594501d01bbdb10f88ab8.tar.gz
Make --nofilesystem=host/home remove access to subdirs of those
Previously --nofilesystem=host only removed specifically access to the `host` permissions, and not necessarily other filesystems (like `home` or `/some/path`). This isn't very useful to limit access because you don't know what other filesystems the app may have access too. We change this to mean that `--nofilesystem=host` removes *all* filesystem access from the parent layer, and `--nofilesystem=home` removes all file access to the homedir and paths inside it. The available layers are, in order: * app permissions * overrides * commandline args This allows you to start from scratch with the filesystem permissions in the overrides or the commandline. This is a small change in behaviour, but not a lot of things use --nofilesystem, and the ones that do probably expects this behaviour. (cherry picked from commit e2c8863fb62301cb05c64bbb32b04446e88ce11a)
-rw-r--r--common/flatpak-context.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/common/flatpak-context.c b/common/flatpak-context.c
index abeda358..4da83e6e 100644
--- a/common/flatpak-context.c
+++ b/common/flatpak-context.c
@@ -851,6 +851,31 @@ flatpak_context_parse_filesystem (const char *filesystem_and_mode,
return FALSE;
}
+/* Note: This only works with valid keys, i.e. they passed flatpak_context_parse_filesystem */
+static gboolean
+flatpak_filesystem_key_in_home (const char *filesystem)
+{
+ /* "home" is definitely in home */
+ if (strcmp (filesystem, "home") == 0)
+ return TRUE;
+
+ /* All the other special fs:es are non-home.
+ * Note: This considers absolute paths that are in the homedir as non-home.
+ */
+ if (g_strv_contains (flatpak_context_special_filesystems, filesystem) ||
+ g_str_has_prefix (filesystem, "/"))
+ return FALSE;
+
+ /* Files in xdg-run are not in home */
+ if (g_str_has_prefix (filesystem, "xdg-run"))
+ return FALSE;
+
+ /* All remaining keys (~/, xdg-data, etc) are considered in home,
+ * Note: technically $XDG_HOME_DATA could point outside the homedir, but we ignore that.
+ */
+ return TRUE;
+}
+
static void
flatpak_context_take_filesystem (FlatpakContext *context,
char *fs,
@@ -865,6 +890,8 @@ flatpak_context_merge (FlatpakContext *context,
{
GHashTableIter iter;
gpointer key, value;
+ gboolean no_home = FALSE;
+ gboolean no_host = FALSE;
context->shares &= ~other->shares_valid;
context->shares |= other->shares;
@@ -887,6 +914,41 @@ flatpak_context_merge (FlatpakContext *context,
while (g_hash_table_iter_next (&iter, &key, &value))
g_hash_table_insert (context->persistent, g_strdup (key), value);
+ /* We first handle all negative home and host as they override other
+ keys than themselves from the parent */
+ if (g_hash_table_lookup_extended (other->filesystems,
+ "host",
+ NULL, &value))
+ {
+ FlatpakFilesystemMode host_mode = GPOINTER_TO_INT (value);
+ if (host_mode == FLATPAK_FILESYSTEM_MODE_NONE)
+ no_host = TRUE;
+ }
+
+ if (g_hash_table_lookup_extended (other->filesystems,
+ "home",
+ NULL, &value))
+ {
+ FlatpakFilesystemMode home_mode = GPOINTER_TO_INT (value);
+ if (home_mode == FLATPAK_FILESYSTEM_MODE_NONE)
+ no_home = TRUE;
+ }
+
+ if (no_host)
+ {
+ g_hash_table_remove_all (context->filesystems);
+ }
+ else if (no_home)
+ {
+ g_hash_table_iter_init (&iter, context->filesystems);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ if (flatpak_filesystem_key_in_home ((const char *)key))
+ g_hash_table_iter_remove (&iter);
+ }
+ }
+
+ /* Then set the new ones, which includes propagating the nohost and nohome ones. */
g_hash_table_iter_init (&iter, other->filesystems);
while (g_hash_table_iter_next (&iter, &key, &value))
g_hash_table_insert (context->filesystems, g_strdup (key), value);