diff --git a/pressure-vessel/flatpak-run-private.h b/pressure-vessel/flatpak-run-private.h index cfe8492dc8585bbcc11802c9b8b5dfa7156938a7..b9a7ac2ec2d9539d8e7c8ce9a5df4668e404ca2f 100644 --- a/pressure-vessel/flatpak-run-private.h +++ b/pressure-vessel/flatpak-run-private.h @@ -52,4 +52,8 @@ GFile *flatpak_get_data_dir (const char *app_id); void flatpak_run_add_font_path_args (FlatpakBwrap *bwrap); extern const char * const *flatpak_abs_usrmerged_dirs; + +int open_namespace_fd_if_needed (const char *path, + const char *other_path); + #endif /* __FLATPAK_RUN_H__ */ diff --git a/pressure-vessel/flatpak-run.c b/pressure-vessel/flatpak-run.c index a096361f6f66d5e12f76d50f943266933e6a1e2d..5b244f72528ad0bfa9367ab28109d84c02616387 100644 --- a/pressure-vessel/flatpak-run.c +++ b/pressure-vessel/flatpak-run.c @@ -3418,8 +3418,9 @@ check_parental_controls (const char *app_ref, return TRUE; } +#endif -static int +int open_namespace_fd_if_needed (const char *path, const char *other_path) { struct stat s, other_s; @@ -3438,6 +3439,7 @@ open_namespace_fd_if_needed (const char *path, return -1; } +#if 0 static gboolean check_sudo (GError **error) { diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index 9e9b4b930513130f340a05ccf4941573af62ea3a..8794d0883c64d3a6a1ca51c6ae3b53f15d3fc135 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -1245,6 +1245,7 @@ main (int argc, g_str_equal, g_free, NULL); g_autofree char *lock_env_fd = NULL; + g_autoptr(GArray) pass_fds_through_adverb = g_array_new (FALSE, FALSE, sizeof (int)); my_pid = getpid (); @@ -2187,6 +2188,49 @@ main (int argc, lock_env_fd = g_strdup_printf ("%d", lock_env_tmpf.fd); flatpak_bwrap_add_fd (bwrap, glnx_steal_fd (&lock_env_tmpf.fd)); + if (is_flatpak_env) + { + int userns_fd, userns2_fd, pidns_fd; + + /* Tell the bwrap instance on the host to join the same user and pid + * namespaces as Steam in Flatpak. Otherwise, pid-based IPC between + * the Steam client and the game will fail. + * + * This is not expected to work if bwrap on the host is setuid, + * so it will not work for users of Debian, Arch linux-hardened, etc., + * but it's better than nothing. */ + userns_fd = open ("/run/.userns", O_RDONLY | O_CLOEXEC); + + if (userns_fd >= 0) + { + g_array_append_val (pass_fds_through_adverb, userns_fd); + flatpak_bwrap_add_args_data_fd (bwrap, "--userns", + glnx_steal_fd (&userns_fd), + NULL); + + userns2_fd = open_namespace_fd_if_needed ("/proc/self/ns/user", + "/run/.userns"); + + if (userns2_fd >= 0) + { + g_array_append_val (pass_fds_through_adverb, userns2_fd); + flatpak_bwrap_add_args_data_fd (bwrap, "--userns2", + glnx_steal_fd (&userns2_fd), + NULL); + } + } + + pidns_fd = open ("/proc/self/ns/pid", O_RDONLY | O_CLOEXEC); + + if (pidns_fd >= 0) + { + g_array_append_val (pass_fds_through_adverb, pidns_fd); + flatpak_bwrap_add_args_data_fd (bwrap, "--pidns", + glnx_steal_fd (&pidns_fd), + NULL); + } + } + if (opt_verbose) { g_message ("%s options before bundling:", bwrap_executable); @@ -2247,6 +2291,13 @@ main (int argc, } } + for (i = 0; i < pass_fds_through_adverb->len; i++) + { + int fd = g_array_index (pass_fds_through_adverb, int, i); + + flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%d", fd); + } + flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%s", lock_env_fd); switch (opt_shell)