diff --git a/src/wrap.c b/src/wrap.c index ab1da9b6a4ded9b318e1304c0e5869b16918fc52..0f711566616eda4b5bb33083567d062a4d895666 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -250,6 +250,12 @@ try_bind_dri (FlatpakBwrap *bwrap, g_autofree gchar *dri = g_build_filename (libdir, "dri", NULL); g_autofree gchar *s2tc = g_build_filename (libdir, "libtxc_dxtn.so", NULL); + /* mount_runtime_on_scratch can't own any fds, because if it did, + * flatpak_bwrap_append_bwrap() would steal them. */ + g_return_val_if_fail (mount_runtime_on_scratch->fds == NULL + || mount_runtime_on_scratch->fds->len == 0, + FALSE); + if (g_file_test (dri, G_FILE_TEST_IS_DIR)) { g_autoptr(FlatpakBwrap) temp_bwrap = NULL; @@ -261,6 +267,8 @@ try_bind_dri (FlatpakBwrap *bwrap, libdir); temp_bwrap = flatpak_bwrap_new (NULL); + g_warn_if_fail (mount_runtime_on_scratch->fds == NULL + || mount_runtime_on_scratch->fds->len == 0); flatpak_bwrap_append_bwrap (temp_bwrap, mount_runtime_on_scratch); flatpak_bwrap_add_args (temp_bwrap, tool_path, @@ -305,6 +313,8 @@ try_bind_dri (FlatpakBwrap *bwrap, expr = g_strdup_printf ("path-match:%s", s2tc); temp_bwrap = flatpak_bwrap_new (NULL); + g_warn_if_fail (mount_runtime_on_scratch->fds == NULL + || mount_runtime_on_scratch->fds->len == 0); flatpak_bwrap_append_bwrap (temp_bwrap, mount_runtime_on_scratch); flatpak_bwrap_add_args (temp_bwrap, tool_path, @@ -374,8 +384,6 @@ bind_runtime (FlatpakBwrap *bwrap, flatpak_bwrap_add_args (bwrap, "--setenv", "XDG_RUNTIME_DIR", xrd, - "--proc", "/proc", - "--ro-bind", "/sys", "/sys", "--tmpfs", "/run", "--tmpfs", "/tmp", "--tmpfs", "/var", @@ -433,50 +441,6 @@ bind_runtime (FlatpakBwrap *bwrap, NULL); } - /* /etc/localtime and /etc/resolv.conf can not exist (or be symlinks to - * non-existing targets), in which case we don't want to attempt to create - * bogus symlinks or bind mounts, as that will cause flatpak run to fail. - */ - if (g_file_test ("/etc/localtime", G_FILE_TEST_EXISTS)) - { - g_autofree char *localtime = NULL; - gboolean is_reachable = FALSE; - g_autofree char *timezone = flatpak_get_timezone (); - g_autofree char *timezone_content = g_strdup_printf ("%s\n", timezone); - - localtime = glnx_readlinkat_malloc (-1, "/etc/localtime", NULL, NULL); - - if (localtime != NULL) - { - g_autoptr(GFile) base_file = NULL; - g_autoptr(GFile) target_file = NULL; - g_autofree char *target_canonical = NULL; - - base_file = g_file_new_for_path ("/etc"); - target_file = g_file_resolve_relative_path (base_file, localtime); - target_canonical = g_file_get_path (target_file); - - is_reachable = g_str_has_prefix (target_canonical, "/usr/"); - } - - if (is_reachable) - { - flatpak_bwrap_add_args (bwrap, - "--symlink", localtime, "/etc/localtime", - NULL); - } - else - { - flatpak_bwrap_add_args (bwrap, - "--ro-bind", "/etc/localtime", "/etc/localtime", - NULL); - } - - flatpak_bwrap_add_args_data (bwrap, "timezone", - timezone_content, -1, "/etc/timezone", - NULL); - } - if (g_file_test ("/etc/resolv.conf", G_FILE_TEST_EXISTS)) flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf", @@ -501,12 +465,6 @@ bind_runtime (FlatpakBwrap *bwrap, "--ro-bind", "/etc/group", "/etc/group", NULL); - flatpak_run_add_wayland_args (bwrap); - flatpak_run_add_x11_args (bwrap, TRUE); - flatpak_run_add_pulseaudio_args (bwrap); - flatpak_run_add_session_dbus_args (bwrap); - flatpak_run_add_system_dbus_args (bwrap); - for (i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++) { g_autofree gchar *tool = g_strdup_printf ("%s-capsule-capture-libs", @@ -589,6 +547,10 @@ bind_runtime (FlatpakBwrap *bwrap, return FALSE; temp_bwrap = flatpak_bwrap_new (NULL); + /* mount_runtime_on_scratch can't own any fds, because if it did, + * flatpak_bwrap_append_bwrap() would steal them. */ + g_warn_if_fail (mount_runtime_on_scratch->fds == NULL + || mount_runtime_on_scratch->fds->len == 0); flatpak_bwrap_append_bwrap (temp_bwrap, mount_runtime_on_scratch); flatpak_bwrap_add_args (temp_bwrap, tool_path, @@ -751,6 +713,9 @@ bind_runtime (FlatpakBwrap *bwrap, g_debug ("Using included locale data from container"); } + if (!pv_bwrap_bind_usr (bwrap, "/", "/run/host", error)) + return FALSE; + if (dri_path->len != 0) flatpak_bwrap_add_args (bwrap, "--setenv", "LIBGL_DRIVERS_PATH", dri_path->str, @@ -760,10 +725,63 @@ bind_runtime (FlatpakBwrap *bwrap, "--unsetenv", "LIBGL_DRIVERS_PATH", NULL); + /* These can add data fds to @bwrap, so they must come last - after + * other functions stop using @bwrap as a basis for their own bwrap + * invocations with flatpak_bwrap_append_bwrap(). + * Otherwise, when flatpak_bwrap_append_bwrap() calls + * flatpak_bwrap_steal_fds(), it will make the original FlatpakBwrap + * unusable. */ + + flatpak_run_add_wayland_args (bwrap); + flatpak_run_add_x11_args (bwrap, TRUE); + flatpak_run_add_pulseaudio_args (bwrap); + flatpak_run_add_session_dbus_args (bwrap); + flatpak_run_add_system_dbus_args (bwrap); pv_bwrap_copy_tree (bwrap, overrides, "/overrides"); - if (!pv_bwrap_bind_usr (bwrap, "/", "/run/host", error)) - return FALSE; + /* /etc/localtime and /etc/resolv.conf can not exist (or be symlinks to + * non-existing targets), in which case we don't want to attempt to create + * bogus symlinks or bind mounts, as that will cause flatpak run to fail. + */ + if (g_file_test ("/etc/localtime", G_FILE_TEST_EXISTS)) + { + g_autofree char *localtime = NULL; + gboolean is_reachable = FALSE; + g_autofree char *timezone = flatpak_get_timezone (); + g_autofree char *timezone_content = g_strdup_printf ("%s\n", timezone); + + localtime = glnx_readlinkat_malloc (-1, "/etc/localtime", NULL, NULL); + + if (localtime != NULL) + { + g_autoptr(GFile) base_file = NULL; + g_autoptr(GFile) target_file = NULL; + g_autofree char *target_canonical = NULL; + + base_file = g_file_new_for_path ("/etc"); + target_file = g_file_resolve_relative_path (base_file, localtime); + target_canonical = g_file_get_path (target_file); + + is_reachable = g_str_has_prefix (target_canonical, "/usr/"); + } + + if (is_reachable) + { + flatpak_bwrap_add_args (bwrap, + "--symlink", localtime, "/etc/localtime", + NULL); + } + else + { + flatpak_bwrap_add_args (bwrap, + "--ro-bind", "/etc/localtime", "/etc/localtime", + NULL); + } + + flatpak_bwrap_add_args_data (bwrap, "timezone", + timezone_content, -1, "/etc/timezone", + NULL); + } return TRUE; } @@ -1587,6 +1605,23 @@ main (int argc, if (opt_terminal != PV_TERMINAL_TTY) flatpak_bwrap_add_arg (bwrap, "--new-session"); + /* Make basic API filesystems available */ + flatpak_bwrap_add_args (bwrap, + "--dev-bind", "/dev", "/dev", + "--proc", "/proc", + "--ro-bind", "/sys", "/sys", + NULL); + + if (g_file_test ("/dev/pts", G_FILE_TEST_EXISTS)) + flatpak_bwrap_add_args (bwrap, + "--dev-bind", "/dev/pts", "/dev/pts", + NULL); + + if (g_file_test ("/dev/shm", G_FILE_TEST_EXISTS)) + flatpak_bwrap_add_args (bwrap, + "--dev-bind", "/dev/shm", "/dev/shm", + NULL); + if (opt_runtime != NULL && opt_runtime[0] != '\0') { g_debug ("Configuring runtime..."); @@ -1623,21 +1658,6 @@ main (int argc, NULL); } - /* Make /dev available */ - flatpak_bwrap_add_args (bwrap, - "--dev-bind", "/dev", "/dev", - NULL); - - if (g_file_test ("/dev/pts", G_FILE_TEST_EXISTS)) - flatpak_bwrap_add_args (bwrap, - "--dev-bind", "/dev/pts", "/dev/pts", - NULL); - - if (g_file_test ("/dev/shm", G_FILE_TEST_EXISTS)) - flatpak_bwrap_add_args (bwrap, - "--dev-bind", "/dev/shm", "/dev/shm", - NULL); - /* Protect other users' homes (but guard against the unlikely * situation that they don't exist) */ if (g_file_test ("/home", G_FILE_TEST_EXISTS))