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 \
--dest io.snapcraft.Launcher \
--object-path /io/snapcraft/PrivilegedDesktopLauncher \
--method io.snapcraft.PrivilegedDesktopLauncher.OpenDesktopEntry \
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
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
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.
/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?