As part of the effort to support a fully confined desktop session, I’ve been experimenting with the experimental desktop-launch
interface implemented by snapd PR #8699. This gives a snap application access to a D-Bus interface that allows it to launch other snap packaged applications via the .desktop
files they install. This was intended as a middle ground between complete isolation and providing back-door access to arbitrary command execution outside the sandbox.
The interface boils down to making D-Bus calls like:
gdbus call \
--session \
--dest io.snapcraft.Launcher \
--object-path /io/snapcraft/PrivilegedDesktopLauncher \
--method io.snapcraft.PrivilegedDesktopLauncher.OpenDesktopEntry \
chromium_chromium.desktop
To make use of this in the prototype, I created new launcher .desktop
files for each application I wanted to be able to launch, using a gdbus call
invocation like above in the Exec=
line.
My thought was that this would eventually be replaced with some code in glib of gnome-shell that would recognise when it was running under confinement and being asked to launch a snap .desktop
file, and call this D-Bus API rather than trying to launch directly. However in discussions yesterday @laney queried whether it would be possible to do this without patching GLib.
The main concerns here were that we don’t want to maintain a patch against GLib (possibly indefinitely), and that it would be nice to have a solution that worked for all implementations of the XDG Desktop File specification rather than just a single one. So that got me thinking about what would be necessary to make that work.
At present, snapd writes out desktop files with Exec lines that look like:
Exec=env BAMF_DESKTOP_FILE_HINT=/var/lib/snapd/desktop/applications/chromium_chromium.desktop /snap/bin/chromium %U
The BAMF_DESKTOP_FILE_HINT
part was intended for use by Unity 7’s old bamf-daemon
to match processes to the desktop file that launched them (by parsing /proc/$pid/environ
). But it also means that command knows which .desktop
file it was run from.
The actual /snap/bin/chromium
here is a symbolic link to /usr/bin/snap
, which does the equivalent to running snap run chromium
when run through the symlink. If the confined application had access to the /snap/bin/*
symlinks and could execute /usr/bin/snap
, then presumably the snap
command could detect that it was running under confinement and instead make the OpenDesktopEntry
D-Bus call. That would effectively make the same desktop file usable both inside and outside of the confinement sandbox.
There are a few variations to this setup that I can think of:
-
rather than calling the regular
/usr/bin/snap
, use layouts to replace that path with our own script (which the/snap/bin/*
symlinks will now point to). -
Rather than complicating the code path used for regular command line invocation of snap commands and services, we could rewrite the desktop files to use a desktop file specific snap sub-command. We’d still have the same “should I run this command directly or delegate via D-Bus?” code, but it would be limited to the case of application launches via desktop files.
What do you think?