From 592bea2b2e17e17120ea9e905defdd518df869f9 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 19 Jan 2017 10:43:17 +0100 Subject: [PATCH] Don't break if exporting paths or symlinks to files in the runtime For instance like in https://github.com/flatpak/flatpak/issues/494 if there is a /linuxrc -> /bin/busybox symlink, and /bin/busybox is not in the runtime then we will fail creating it as a mountpoint for the bind mount. Fixes https://github.com/flatpak/flatpak/issues/494 --- common/flatpak-run.c | 51 +++++++++++++++++++++++++++++++----------- common/flatpak-utils.c | 7 ++++++ common/flatpak-utils.h | 1 + 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/common/flatpak-run.c b/common/flatpak-run.c index 92c9908e9..39d4a4d39 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -93,6 +93,12 @@ const char *dont_mount_in_root[] = { "tmp", "etc", "app", "run", "proc", "sys", "dev", "var", NULL }; +/* We don't want to export paths pointing into these, because they are readonly + (so we can't create mountpoints there) and don't match whats on the host anyway */ +const char *dont_export_in[] = { + "/lib/", "/lib32/", "/lib64/", "/bin/", "/sbin/", "/usr/", "/etc/", "/app/", NULL +}; + typedef enum { FLATPAK_CONTEXT_DEVICE_DRI = 1 << 0, FLATPAK_CONTEXT_DEVICE_ALL = 1 << 1, @@ -2286,15 +2292,35 @@ add_hide_path (GHashTable *hash_table, GINT_TO_POINTER ( MAX (old_mode, FAKE_MODE_HIDDEN))); } -static void +static gboolean add_expose_path (GHashTable *hash_table, FlatpakFilesystemMode mode, const char *path) { + g_autofree char *canonical = flatpak_canonicalize_filename (path); struct stat st; + int i; + + if (!g_path_is_absolute (path)) + { + g_warning ("Exposing relative path %s", path); + return FALSE; + } + + for (i = 0; dont_export_in[i] != NULL; i++) + { + /* Don't expose files in non-mounted dirs like /app or /usr, as + they are not the same as on the host, and we generally can't + create the parents for them anyway */ + if (g_str_has_prefix (canonical, dont_export_in[i])) + { + g_debug ("skipping export for path %s", canonical); + return FALSE; + } + } if (lstat (path, &st) != 0) - return; + return FALSE; if (S_ISDIR (st.st_mode) || S_ISREG (st.st_mode) || @@ -2308,22 +2334,21 @@ add_expose_path (GHashTable *hash_table, if (S_ISLNK (st.st_mode)) { g_autofree char *resolved = flatpak_resolve_link (path, NULL); - /* Don't keep symlinks into /app or /usr, as they are not the - same as on the host, and we generally can't create the parents - for them anyway */ - if (resolved && - !g_str_has_prefix (resolved, "/app/") && - !g_str_has_prefix (resolved, "/usr/")) - { - add_expose_path (hash_table, mode, resolved); - mode = FAKE_MODE_SYMLINK; - } + + if (resolved && add_expose_path (hash_table, mode, resolved)) + mode = FAKE_MODE_SYMLINK; else mode = 0; } + if (mode > 0) - g_hash_table_insert (hash_table, g_strdup (path), GINT_TO_POINTER ( MAX (old_mode, mode))); + { + g_hash_table_insert (hash_table, g_strdup (path), GINT_TO_POINTER ( MAX (old_mode, mode))); + return TRUE; + } } + + return FALSE; } void diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c index ce6a3bc45..2f16a25dd 100644 --- a/common/flatpak-utils.c +++ b/common/flatpak-utils.c @@ -2185,6 +2185,13 @@ flatpak_resolve_link (const char *path, return g_build_path (dirname, link, NULL); } +char * +flatpak_canonicalize_filename (const char *path) +{ + g_autoptr(GFile) file = g_file_new_for_path (path); + return g_file_get_path (file); +} + gboolean flatpak_file_rename (GFile *from, GFile *to, GCancellable *cancellable, diff --git a/common/flatpak-utils.h b/common/flatpak-utils.h index 757fe0675..2bd2e8a4e 100644 --- a/common/flatpak-utils.h +++ b/common/flatpak-utils.h @@ -383,6 +383,7 @@ char * flatpak_readlink (const char *path, GError **error); char * flatpak_resolve_link (const char *path, GError **error); +char * flatpak_canonicalize_filename (const char *path); gboolean flatpak_file_rename (GFile *from, GFile *to,