On 11/13/25 06:10, Alyssa Ross wrote:
After working on it for a while, I decided that it complicated the D-Bus security model too much to upstream VSOCK support for the bus. Proxying D-Bus with socat will allow us to drop the D-Bus VSOCK patches.
The new dbus-vsock service starts before dbus-daemon to ensure that VSOCK connections can be received as soon as org.freedesktop.impl.portal.desktop.spectrum is started. When a connection is received (which should only be after the bus is up and has started org.freedesktop.impl.portal.desktop.spectrum), it will be relayed to the bus.
Sadly we do still need to allow ANONYMOUS authentication for now[1].
Signed-off-by: Alyssa Ross <hi@alyssa.is> Link: https://github.com/z-galaxy/zbus/issues/1003#issuecomment-3523214990 [1] --- img/app/default.nix | 4 +- img/app/file-list.mk | 5 +++ img/app/image/etc/dbus-1/session.conf | 1 - .../XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT | 1 + ...DESKTOP_PORTAL_SPECTRUM_GUEST_PORT.license | 2 + .../etc/s6-rc/dbus-vsock/notification-fd | 1 + .../s6-rc/dbus-vsock/notification-fd.license | 2 + img/app/image/etc/s6-rc/dbus-vsock/run | 17 +++++++ img/app/image/etc/s6-rc/dbus-vsock/type | 1 + .../image/etc/s6-rc/dbus-vsock/type.license | 2 + .../etc/s6-rc/dbus/dependencies.d/dbus-vsock | 0 img/app/image/etc/s6-rc/dbus/run | 2 - tools/default.nix | 5 +-- tools/xdg-desktop-portal-spectrum/meson.build | 3 -- .../xdg-desktop-portal-spectrum.c | 45 ++++++------------- 15 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT create mode 100644 img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT.license create mode 100644 img/app/image/etc/s6-rc/dbus-vsock/notification-fd create mode 100644 img/app/image/etc/s6-rc/dbus-vsock/notification-fd.license create mode 100755 img/app/image/etc/s6-rc/dbus-vsock/run create mode 100644 img/app/image/etc/s6-rc/dbus-vsock/type create mode 100644 img/app/image/etc/s6-rc/dbus-vsock/type.license create mode 100644 img/app/image/etc/s6-rc/dbus/dependencies.d/dbus-vsock
diff --git a/img/app/default.nix b/img/app/default.nix index 08cb2cd..6490ac2 100644 --- a/img/app/default.nix +++ b/img/app/default.nix @@ -71,6 +71,8 @@ let pkgs.s6 pkgs.s6-linux-init pkgs.s6-rc + pkgs.socat + pkgs.systemd pkgs.wayland-proxy-virtwl pkgs.wireplumber pkgs.xdg-desktop-portal @@ -88,7 +90,7 @@ let } '' mkdir $out lndir -ignorelinks -silent ${appimageFhsenv} $out - rm $out/etc/dbus-1/session.conf + rm $out/etc/dbus-1/session.conf $out/usr/bin/init ''; in
diff --git a/img/app/file-list.mk b/img/app/file-list.mk index 0b4d3d1..6934975 100644 --- a/img/app/file-list.mk +++ b/img/app/file-list.mk @@ -17,6 +17,7 @@ FILES = \ image/etc/s6-linux-init/env/GTK_USE_PORTAL \ image/etc/s6-linux-init/env/NIX_XDG_DESKTOP_PORTAL_DIR \ image/etc/s6-linux-init/env/WAYLAND_DISPLAY \ + image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT \ image/etc/s6-linux-init/env/XDG_RUNTIME_DIR \ image/etc/s6-linux-init/run-image/service/getty-hvc0/run \ image/etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/notification-fd \ @@ -39,6 +40,10 @@ S6_RC_FILES = \ image/etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl \ image/etc/s6-rc/app/run \ image/etc/s6-rc/app/type \ + image/etc/s6-rc/dbus-vsock/notification-fd \ + image/etc/s6-rc/dbus-vsock/run \ + image/etc/s6-rc/dbus-vsock/type \ + image/etc/s6-rc/dbus/dependencies.d/dbus-vsock \ image/etc/s6-rc/dbus/notification-fd \ image/etc/s6-rc/dbus/run \ image/etc/s6-rc/dbus/type \ diff --git a/img/app/image/etc/dbus-1/session.conf b/img/app/image/etc/dbus-1/session.conf index 751a788..d31f4b9 100644 --- a/img/app/image/etc/dbus-1/session.conf +++ b/img/app/image/etc/dbus-1/session.conf @@ -19,7 +19,6 @@ default config file with an address override on the command line, because command line address can only be given once. So that's why we need a whole custom session.conf. --> - <listen>vsock:</listen> <listen>unix:path=/run/session-bus</listen>
<auth>EXTERNAL</auth> diff --git a/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT b/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT new file mode 100644 index 0000000..037ba97 --- /dev/null +++ b/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT @@ -0,0 +1 @@ +219 diff --git a/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT.license b/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT.license new file mode 100644 index 0000000..0d3d47c --- /dev/null +++ b/img/app/image/etc/s6-linux-init/env/XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is> diff --git a/img/app/image/etc/s6-rc/dbus-vsock/notification-fd b/img/app/image/etc/s6-rc/dbus-vsock/notification-fd new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/img/app/image/etc/s6-rc/dbus-vsock/notification-fd @@ -0,0 +1 @@ +3 diff --git a/img/app/image/etc/s6-rc/dbus-vsock/notification-fd.license b/img/app/image/etc/s6-rc/dbus-vsock/notification-fd.license new file mode 100644 index 0000000..0d3d47c --- /dev/null +++ b/img/app/image/etc/s6-rc/dbus-vsock/notification-fd.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is> diff --git a/img/app/image/etc/s6-rc/dbus-vsock/run b/img/app/image/etc/s6-rc/dbus-vsock/run new file mode 100755 index 0000000..37fae7d --- /dev/null +++ b/img/app/image/etc/s6-rc/dbus-vsock/run @@ -0,0 +1,17 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2+ +# SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is> + +if { modprobe vsock } + +export LISTEN_FDS 1 +getpid LISTEN_PID +export SYSTEMD_LOG_LEVEL notice + +systemd-socket-activate -l vsock::219 --now + +# Notify readiness. +if { fdmove 1 3 echo } +fdclose 3 + +socat ACCEPT-FD:4,fork UNIX-CONNECT:/run/session-bus diff --git a/img/app/image/etc/s6-rc/dbus-vsock/type b/img/app/image/etc/s6-rc/dbus-vsock/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/img/app/image/etc/s6-rc/dbus-vsock/type @@ -0,0 +1 @@ +longrun diff --git a/img/app/image/etc/s6-rc/dbus-vsock/type.license b/img/app/image/etc/s6-rc/dbus-vsock/type.license new file mode 100644 index 0000000..0d3d47c --- /dev/null +++ b/img/app/image/etc/s6-rc/dbus-vsock/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is> diff --git a/img/app/image/etc/s6-rc/dbus/dependencies.d/dbus-vsock b/img/app/image/etc/s6-rc/dbus/dependencies.d/dbus-vsock new file mode 100644 index 0000000..e69de29 diff --git a/img/app/image/etc/s6-rc/dbus/run b/img/app/image/etc/s6-rc/dbus/run index a226abf..75e9cab 100644 --- a/img/app/image/etc/s6-rc/dbus/run +++ b/img/app/image/etc/s6-rc/dbus/run @@ -2,8 +2,6 @@ # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2023 Alyssa Ross <hi@alyssa.is>
-if { modprobe vsock } - dbus-daemon --config-file /etc/dbus-1/session.conf --nofork diff --git a/tools/default.nix b/tools/default.nix index 18d4dd6..0492f98 100644 --- a/tools/default.nix +++ b/tools/default.nix @@ -6,7 +6,7 @@ import ../lib/call-package.nix ( { src, lib, stdenv, fetchCrate, fetchurl, runCommand, buildPackages , meson, ninja, pkg-config, rustc , clang-tools, clippy, jq -, dbus, linuxHeaders +, linuxHeaders , clang, libbpf , buildSupport ? false , appSupport ? true @@ -88,8 +88,7 @@ stdenv.mkDerivation (finalAttrs: { ++ lib.optionals (appSupport || driverSupport) [ pkg-config ] ++ lib.optionals hostSupport [ rustc ] ++ lib.optionals driverSupport [ clang.cc ]; - buildInputs = lib.optionals appSupport [ dbus ] - ++ lib.optionals driverSupport [ libbpf linuxHeaders ]; + buildInputs = lib.optionals driverSupport [ libbpf linuxHeaders ];
postPatch = lib.optionals hostSupport (lib.concatMapStringsSep "\n" (crate: '' mkdir -p subprojects/packagecache diff --git a/tools/xdg-desktop-portal-spectrum/meson.build b/tools/xdg-desktop-portal-spectrum/meson.build index 7c2716f..a99c66d 100644 --- a/tools/xdg-desktop-portal-spectrum/meson.build +++ b/tools/xdg-desktop-portal-spectrum/meson.build @@ -1,8 +1,6 @@ # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2024 Alyssa Ross <hi@alyssa.is>
-dbus = dependency('dbus-1') - install_data('spectrum.portal', install_dir : get_option('datadir') / 'xdg-desktop-portal/portals')
@@ -21,5 +19,4 @@ configure_file( configuration : exe_conf_data)
executable('xdg-desktop-portal-spectrum', 'xdg-desktop-portal-spectrum.c', - dependencies : dbus, install : true) diff --git a/tools/xdg-desktop-portal-spectrum/xdg-desktop-portal-spectrum.c b/tools/xdg-desktop-portal-spectrum/xdg-desktop-portal-spectrum.c index 690d397..3c75923 100644 --- a/tools/xdg-desktop-portal-spectrum/xdg-desktop-portal-spectrum.c +++ b/tools/xdg-desktop-portal-spectrum/xdg-desktop-portal-spectrum.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: EUPL-1.2+ -// SPDX-FileCopyrightText: 2024 Alyssa Ross <hi@alyssa.is> +// SPDX-FileCopyrightText: 2024-2025 Alyssa Ross <hi@alyssa.is>
#include <arpa/inet.h> #include <err.h> @@ -8,7 +8,6 @@ #include <stdio.h> #include <stdint.h> #include <stdlib.h> -#include <string.h> #include <unistd.h>
#include <sys/socket.h> @@ -16,12 +15,13 @@
#include <linux/vm_sockets.h>
-#include <dbus/dbus.h> - #include "config.h"
static const uint32_t HOST_PORT = 219;
+static const char GUEST_PORT_ENV_VAR[] = + "XDG_DESKTOP_PORTAL_SPECTRUM_GUEST_PORT"; + static int parse_u32(const char *s, uint32_t *v) { char *end; @@ -113,36 +113,17 @@ static void check_result(int sock)
int main(void) { - char *addr = getenv("DBUS_STARTER_ADDRESS"); - - DBusAddressEntry **entries; - int entries_len, i, sock; - DBusError error; - - const char *port_str; + int sock; uint32_t port; + char *port_str = getenv(GUEST_PORT_ENV_VAR);
- if (!addr) - errx(EXIT_FAILURE, "DBUS_STARTER_ADDRESS not set"); + if (!port_str) + errx(EXIT_FAILURE, "%s is not set", GUEST_PORT_ENV_VAR);
- if (!dbus_parse_address(addr, &entries, &entries_len, &error)) - errx(EXIT_FAILURE, "parsing D-Bus address '%s': %s", - addr, error.message); + if (parse_u32(port_str, &port) == -1) + err(EXIT_FAILURE, "D-Bus address vsock port");
- for (i = 0; i < entries_len; i++) { - if (strcmp(dbus_address_entry_get_method(entries[i]), "vsock")) - continue; - - if (!(port_str = dbus_address_entry_get_value(entries[i], "port"))) - errx(EXIT_FAILURE, "missing vsock port in D-Bus address '%s'", - addr); - - if (parse_u32(port_str, &port) == -1) - err(EXIT_FAILURE, "D-Bus address vsock port"); - - sock = connect_to_host(); - send_info(sock, port); - check_result(sock); - return 0; - } + sock = connect_to_host(); + send_info(sock, port); + check_result(sock); }
Assuming it passes tests: Acked-by: Demi Marie Obenour <demiobenour@gmail.com> socat could be replaced with systemd-socket-proxyd, which avoids forking a process for each connection. That's definitely a very minor nit, though. -- Sincerely, Demi Marie Obenour (she/her/hers)