From a127fb49cbd90692afe294855a8a36bfeb2f6e8f Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Thu, 27 Mar 2025 19:24:26 +0000 Subject: [PATCH] wrap-setup: Bind-mount in the AT-SPI accessibility bus AT-SPI has its own private D-Bus message bus, the "accessibility bus". This is used to let applications export their window contents to assistive technologies such as screen readers, and to let assistive technologies send events to the applications. This avoids flooding the session bus with AT-SPI traffic, which can be rather frequent. If we want `steamwebhelper` to be accessible to assistive technologies, it needs to be able to communicate with that bus. In older AT-SPI it was an abstract AF_UNIX socket, which passes through "naturally", but in newer AT-SPI it has been changed to be a filesystem-backed AF_UNIX socket in order to allow sandboxing, therefore the socket needs to be bind-mounted into our container. As with the session bus, we can adapt Flatpak's code for this: Flatpak would always use a proxy in order to impose a security boundary, but pressure-vessel is specifically not a security boundary, so we can simplify considerably. steamrt/tasks#699 Signed-off-by: Simon McVittie <smcv@collabora.com> --- pressure-vessel/flatpak-run-dbus-private.h | 1 + pressure-vessel/flatpak-run-dbus.c | 53 +++++++++++++++++++--- pressure-vessel/wrap-setup.c | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/pressure-vessel/flatpak-run-dbus-private.h b/pressure-vessel/flatpak-run-dbus-private.h index af950beb0..d78e4ffc3 100644 --- a/pressure-vessel/flatpak-run-dbus-private.h +++ b/pressure-vessel/flatpak-run-dbus-private.h @@ -56,6 +56,7 @@ gboolean flatpak_run_maybe_start_dbus_proxy (FlatpakBwrap *app_bwrap, /* Simplified interface for pressure-vessel */ gboolean flatpak_run_add_session_dbus_args (FlatpakBwrap *app_bwrap); gboolean flatpak_run_add_system_dbus_args (FlatpakBwrap *app_bwrap); +gboolean flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap); #endif G_END_DECLS diff --git a/pressure-vessel/flatpak-run-dbus.c b/pressure-vessel/flatpak-run-dbus.c index 4eed6dbed..34dcb60b8 100644 --- a/pressure-vessel/flatpak-run-dbus.c +++ b/pressure-vessel/flatpak-run-dbus.c @@ -404,12 +404,8 @@ flatpak_run_add_system_dbus_args (FlatpakBwrap *app_bwrap) return FALSE; } -#if 0 gboolean -flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap, - FlatpakBwrap *proxy_arg_bwrap, - FlatpakContext *context, - FlatpakRunFlags flags) +flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap) { static const char sandbox_socket_path[] = "/run/pressure-vessel/at-spi-bus"; static const char sandbox_dbus_address[] = "unix:path=/run/pressure-vessel/at-spi-bus"; @@ -418,11 +414,15 @@ flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap, g_autoptr(GError) local_error = NULL; g_autoptr(GDBusMessage) reply = NULL; g_autoptr(GDBusMessage) msg = NULL; +#if 0 g_autofree char *proxy_socket = NULL; +#endif const char *value; +#if 0 if ((flags & FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY) != 0) return FALSE; +#endif session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (session_bus == NULL) @@ -470,6 +470,47 @@ flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap, } } +#if 1 + /* Simplified from Flatpak: we don't restrict access or use a proxy, + * we just pass the socket through as-is */ + { + g_autofree char *a11y_socket = NULL; + struct stat statbuf; + + /* If AT-SPI is listening on an abstract AF_UNIX socket, then there + * is no socket to listen on, but that's fine because there is also + * no need to bind-mount anything: we don't unshare the network + * namespace, so the container will have access to all abstract + * sockets. In this case we can just return false and the right thing + * will happen. */ + + if (a11y_address != NULL) + a11y_socket = extract_unix_path_from_dbus_address (a11y_address); + + if (a11y_socket == NULL) + { + g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir (); + + /* Typical path on systemd systems */ + a11y_socket = g_build_filename (user_runtime_dir, "at-spi", "bus", NULL); + } + + if (a11y_socket == NULL + || stat (a11y_socket, &statbuf) < 0 + || (statbuf.st_mode & S_IFMT) != S_IFSOCK + || statbuf.st_uid != getuid ()) + return FALSE; + + flatpak_bwrap_add_args (app_bwrap, + "--ro-bind", a11y_socket, sandbox_socket_path, + NULL); + flatpak_bwrap_set_env (app_bwrap, "AT_SPI_BUS_ADDRESS", sandbox_dbus_address, TRUE); + flatpak_bwrap_add_runtime_dir_member (app_bwrap, "at-spi-bus"); + } + +#else + /* Original implementation from Flatpak */ + if (!a11y_address) return FALSE; @@ -498,7 +539,7 @@ flatpak_run_add_a11y_dbus_args (FlatpakBwrap *app_bwrap, "--ro-bind", proxy_socket, sandbox_socket_path, NULL); flatpak_bwrap_set_env (app_bwrap, "AT_SPI_BUS_ADDRESS", sandbox_dbus_address, TRUE); +#endif return TRUE; } -#endif diff --git a/pressure-vessel/wrap-setup.c b/pressure-vessel/wrap-setup.c index edda14e40..f0f5b48c6 100644 --- a/pressure-vessel/wrap-setup.c +++ b/pressure-vessel/wrap-setup.c @@ -205,6 +205,7 @@ pv_wrap_share_sockets (SrtEnvOverlay *container_env, flatpak_run_add_session_dbus_args (sharing_bwrap); flatpak_run_add_system_dbus_args (sharing_bwrap); flatpak_run_add_socket_args_late (sharing_bwrap, shares); + flatpak_run_add_a11y_dbus_args (sharing_bwrap); pv_wrap_add_pipewire_args (sharing_bwrap, container_env); pv_wrap_add_discord_args (sharing_bwrap); } -- GitLab