run: Create a shared XDG_RUNTIME_DIR for each app-ID

Like $XDG_RUNTIME_DIR/app/$FLATPAK_ID, this is shared between all
instances of the app, except for subsandboxed instances created by
flatpak-spawn --sandbox or equivalent. Unlike
$XDG_RUNTIME_DIR/app/$FLATPAK_ID, it does not exist at an equivalent
path on the host and in the sandboxed app.

Resolves: https://github.com/flatpak/flatpak/issues/4120
Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie
2021-04-09 14:42:12 +01:00
committed by Alexander Larsson
parent 40510e8ae8
commit 38eac07293
7 changed files with 119 additions and 12 deletions

View File

@@ -580,7 +580,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError
NULL);
}
flatpak_bwrap_populate_runtime_dir (bwrap);
flatpak_bwrap_populate_runtime_dir (bwrap, NULL);
flatpak_bwrap_envp_to_args (bwrap);

View File

@@ -85,7 +85,8 @@ gboolean flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap,
GError **error);
void flatpak_bwrap_add_runtime_dir_member (FlatpakBwrap *bwrap,
const char *name);
void flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap);
void flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap,
const char *shared_xdg_runtime_dir);
void flatpak_bwrap_child_setup_cb (gpointer user_data);
void flatpak_bwrap_child_setup (GArray *fd_array,

View File

@@ -417,12 +417,51 @@ flatpak_bwrap_add_runtime_dir_member (FlatpakBwrap *bwrap,
g_ptr_array_add (bwrap->runtime_dir_members, g_strdup (name));
}
void
flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap)
static void
expect_symlink (const char *host_path,
const char *target)
{
flatpak_bwrap_add_arg (bwrap, "--symlink");
flatpak_bwrap_add_arg (bwrap, "../../../.flatpak-info");
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/flatpak-info", getuid ());
/* This shouldn't fail in practice, so there's not much point in
* translating the warning */
if (symlink (target, host_path) < 0 && errno != EEXIST)
{
g_warning ("Unable to create symlink at %s: %s",
host_path, g_strerror (errno));
}
else
{
g_autoptr(GError) local_error = NULL;
g_autofree char *got = glnx_readlinkat_malloc (AT_FDCWD,
host_path,
NULL,
&local_error);
if (got == NULL)
g_warning ("%s is not a symlink to \"%s\" as expected: %s",
host_path, target, local_error->message);
else if (strcmp (got, target) != 0)
g_warning ("%s is a symlink to \"%s\", not \"%s\" as expected",
host_path, got, target);
}
}
void
flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap,
const char *shared_xdg_runtime_dir)
{
if (shared_xdg_runtime_dir != NULL)
{
g_autofree char *host_path = g_build_filename (shared_xdg_runtime_dir,
"flatpak-info", NULL);
expect_symlink (host_path, "../../../.flatpak-info");
}
else
{
flatpak_bwrap_add_arg (bwrap, "--symlink");
flatpak_bwrap_add_arg (bwrap, "../../../.flatpak-info");
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/flatpak-info", getuid ());
}
if (bwrap->runtime_dir_members != NULL)
{
@@ -431,10 +470,21 @@ flatpak_bwrap_populate_runtime_dir (FlatpakBwrap *bwrap)
for (i = 0; i < bwrap->runtime_dir_members->len; i++)
{
const char *member = g_ptr_array_index (bwrap->runtime_dir_members, i);
g_autofree char *target = g_strdup_printf ("../../flatpak/%s", member);
flatpak_bwrap_add_arg (bwrap, "--symlink");
flatpak_bwrap_add_arg_printf (bwrap, "../../flatpak/%s", member);
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/%s", getuid (), member);
if (shared_xdg_runtime_dir != NULL)
{
g_autofree char *host_path = g_build_filename (shared_xdg_runtime_dir,
member, NULL);
expect_symlink (host_path, target);
}
else
{
flatpak_bwrap_add_arg (bwrap, "--symlink");
flatpak_bwrap_add_arg (bwrap, target);
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d/%s", getuid (), member);
}
}
}
}

View File

@@ -7857,7 +7857,7 @@ apply_extra_data (FlatpakDir *self,
NULL, cancellable, error))
return FALSE;
flatpak_bwrap_populate_runtime_dir (bwrap);
flatpak_bwrap_populate_runtime_dir (bwrap, NULL);
flatpak_bwrap_envp_to_args (bwrap);

View File

@@ -52,5 +52,9 @@ gboolean flatpak_instance_ensure_per_app_tmp (const char *app_id,
int per_app_dir_lock_fd,
char **shared_tmp_out,
GError **error);
gboolean flatpak_instance_ensure_per_app_xdg_runtime_dir (const char *app_id,
int per_app_dir_lock_fd,
char **shared_dir_out,
GError **error);
#endif /* __FLATPAK_INSTANCE_PRIVATE_H__ */

View File

@@ -671,6 +671,47 @@ flatpak_instance_ensure_per_app_tmp (const char *app_id,
return TRUE;
}
/*
* @app_id: $FLATPAK_ID
* @per_app_dir_lock_fd: Used to prove that we have already taken out
* a per-app non-exclusive lock to stop this directory from being
* garbage-collected
* @shared_dir_out: (out) (not optional) (not nullable): Used to return
* the path to the shared $XDG_RUNTIME_DIR
*
* Create a per-app $XDG_RUNTIME_DIR.
*/
gboolean
flatpak_instance_ensure_per_app_xdg_runtime_dir (const char *app_id,
int per_app_dir_lock_fd,
char **shared_dir_out,
GError **error)
{
g_autofree char *per_app_parent = NULL;
g_autofree char *shared_dir = NULL;
g_return_val_if_fail (app_id != NULL, FALSE);
g_return_val_if_fail (shared_dir_out != NULL, FALSE);
g_return_val_if_fail (*shared_dir_out == NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* We don't actually do anything with this, we just pass it in here as
* proof that we already set up the directory that contains the lock
* file for per-app things, to force us to get the sequence right */
g_return_val_if_fail (per_app_dir_lock_fd >= 0, FALSE);
per_app_parent = flatpak_instance_get_apps_directory ();
shared_dir = g_build_filename (per_app_parent, app_id, "xdg-run", NULL);
if (g_mkdir_with_parents (shared_dir, 0700) != 0)
return glnx_throw_errno_prefix (error,
_("Unable to create directory %s"),
shared_dir);
*shared_dir_out = g_steal_pointer (&shared_dir);
return TRUE;
}
/*
* @host_dir_out: (not optional): used to return the directory on the host
* system representing this instance

View File

@@ -3834,6 +3834,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
g_autofree char *checksum = NULL;
glnx_autofd int per_app_dir_lock_fd = -1;
g_autofree char *per_app_dir_lock_path = NULL;
g_autofree char *shared_xdg_runtime_dir = NULL;
int ld_so_fd = -1;
g_autoptr(GFile) runtime_ld_so_conf = NULL;
gboolean generate_ld_so_conf = TRUE;
@@ -4261,6 +4262,16 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
&per_app_dir_lock_path,
error))
return FALSE;
if (!flatpak_instance_ensure_per_app_xdg_runtime_dir (app_id,
per_app_dir_lock_fd,
&shared_xdg_runtime_dir,
error))
return FALSE;
flatpak_bwrap_add_arg (bwrap, "--bind");
flatpak_bwrap_add_arg (bwrap, shared_xdg_runtime_dir);
flatpak_bwrap_add_arg_printf (bwrap, "/run/user/%d", getuid ());
}
if (!flatpak_run_add_dconf_args (bwrap, app_id, metakey, error))
@@ -4330,7 +4341,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
flatpak_bwrap_add_args_data_fd (bwrap, "--pidns", pidns_fd, NULL);
}
flatpak_bwrap_populate_runtime_dir (bwrap);
flatpak_bwrap_populate_runtime_dir (bwrap, shared_xdg_runtime_dir);
if (custom_command)
{