Private shared memory support for snaps
by Igor Ljubuncic on 14 April 2022
At first glance, the title of this article may sound like an oxymoron. However, what it highlights is the introduction of a rather useful feature that will enable a far more robust and elegant handling of the /dev/shm implementation inside the snap sandbox. This will make snap development easier, more secure, and reduce potential bugs in browser-like apps.
A little bit of history and reasoning for the status quo
Snaps are self-contained application archives, isolated from the underlying operating system (as a security and robustness measure). To make snaps practical, granular access to specific system resources is available through a mechanism of interfaces. Snap developers can declare one or more plugs to different interfaces in their snapcraft.yaml file during the build process, and at runtime, the snapd service will connect these plugs to their corresponding slots for the declared interfaces, and allow the required functionality.
More recent versions of snapd also support the shared-memory interface, which allows snaps to communicate with each other using predefined paths under /dev/shm. The location is defined by one snap and connected to from another. By and large, the usage is fairly straightforward, but in some cases, problems may occur due to shared memory segment naming rules. This can affect a variety of applications, but it is most common with browser-like applications or those that embed browser-like frameworks (like Electron/Chromium).
One of the core promises of the snap ecosystem is that it guarantees consistent behavior and functionality of snapped applications on all supported platforms. As part of the ongoing effort to make the overall experience even more robust, the snapd has recently proposed and developed a new concept of private shared memory, which should minimize naming conflicts, and allowed snaps that rely on /dev/shm to work without any issues.
Private shared memory, details
The principle behind the improved shared memory functionality is to extend the capability of the existing interface. A new mode, whereby a new shared memory implicit slot is added, and when a snap connects to this slot, a private directory is mounted over /dev/shm. This removes all shm naming restrictions for the snap. That said, snaps with the above declaration can no longer share memory segments with processes outside of the snap. However, few snaps typically use cross-snap communication, so for most use cases, the private shm capability is an improvement.
The technical details are a little tricky, but in essence, the new mode implementation works as follows. First, it checks whether it is enabled (set to true or false). If the snap developer has declared the private mode to true in their snapcraft.yaml, then snapd will check whether the implementation is actually possible, i.e., make sure that shared memory is not set and that there aren’t any other shared-memory interface plugs or slots declared in the snap.
Once the prerequisites are satisfied, snapd will then update the AppArmor rules, and bind-mount the snap’s private memory path to /dev/shm, and update any other rules to allow for seamless functionality, without breaking the security confinement or degrading the existing security restrictions inherited from the underlying host system. The other benefit is that this improves security for all apps that use the browser-support interface. At present, all snaps with this interface plugged can potentially access each other’s shm elements. The private memory plug closes off that access.
Private shared memory can be enabled in a snap by adding the following top-level declaration to the snapcraft.yaml:
With that, snaps using /dev/shm should not experience any conflict with other snaps on the system leading to an improved and more stable usability.
The new private shared memory support is part of the snapd 2.55.3 release, and it is available both in the Ubuntu 22.04 archive as well the candidate channel (in the Snap Store) on older releases of the distribution. It can be used as is, without any experimental flags.
We’d like to call upon all the tinkerers to install this new version of snapd and test the private shared memory functionality. Likewise, if you have any other feedback or ideas regarding shared memory, please join our forum and let us know what you think.