run: Add (ro-)bind fds to flatpak_run_app

The flatpak portal allows apps to expose files and folders from within
the sandbox to a side-sandbox using flatpak-spawn. So far it has used
the --filesystem option to mount those files and folders, but it takes a
path. Paths are inherently racy and they allow the app to swap out any
component of the path with a symlink after handing it off. If they win
the race, flatpak will mount a completely different directory.

This adds a new way to mount files and directories based on O_PATH
file descriptor that needs to provided when execing the flatpak binary.
This commit is contained in:
Sebastian Wick
2026-02-06 21:02:47 +01:00
committed by Sebastian Wick
parent 494c5ea687
commit 4f1e7f8d17
4 changed files with 41 additions and 0 deletions

View File

@@ -385,6 +385,8 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
opt_instance_id_fd,
(const char * const *) run_environ,
NULL,
NULL,
NULL,
cancellable,
error))
return FALSE;

View File

@@ -714,6 +714,7 @@ flatpak_installation_launch_full (FlatpakInstallation *self,
NULL, 0, -1,
(const char * const *) run_environ,
&instance_dir,
NULL, NULL,
cancellable, error))
return FALSE;

View File

@@ -124,6 +124,8 @@ gboolean flatpak_run_app (FlatpakDecomposed *app_ref,
int instance_id_fd,
const char * const *run_environ,
char **instance_dir_out,
GArray *bind_fds,
GArray *ro_bind_fds,
GCancellable *cancellable,
GError **error);

View File

@@ -2979,6 +2979,8 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
int instance_id_fd,
const char * const *run_environ,
char **instance_dir_out,
GArray *bind_fds,
GArray *ro_bind_fds,
GCancellable *cancellable,
GError **error)
{
@@ -3583,6 +3585,40 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d", getuid ());
}
for (i = 0; bind_fds && i < bind_fds->len; i++)
{
int fd = g_array_index (bind_fds, int, i);
g_autofree char *path = NULL;
/* We get the path the fd refers to, to determine to mount point
* destination inside the sandbox */
path = get_path_for_fd (fd, error);
if (!path)
return FALSE;
if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
"--bind-fd", fd, path,
error))
return FALSE;
}
for (i = 0; ro_bind_fds && i < ro_bind_fds->len; i++)
{
int fd = g_array_index (ro_bind_fds, int, i);
g_autofree char *path = NULL;
/* We get the path the fd refers to, to determine to mount point
* destination inside the sandbox */
path = get_path_for_fd (fd, error);
if (!path)
return FALSE;
if (!flatpak_bwrap_add_args_data_fd_dup (bwrap,
"--ro-bind-fd", fd, path,
error))
return FALSE;
}
if (!flatpak_run_add_dconf_args (bwrap, app_id, metakey, error))
return FALSE;