As a part of fixing https://bugs.launchpad.net/snapd/+bug/1838937 I realized the device cgroup needs some non-trivial changes. Let me explain my thought process quickly.
The issue is that, effectively, we don’t create the device cgroup when there are no devices tagged to a specific snap application. When such devices are then added to the system (connecting a device) or when the set of tagging rules changes (connecting a snap interface) then the changes are applied to a cgroup other than the one used by running application.
To fix that we can create a device cgroup and always put processes in it, one for each snap application or hook. The cgroup must have one of two configurations:
- Unconfined: allowing access to all devices
- Confined: allowing access to more-less fixed number of devices as well as all the tagged devices
The unconfined configuration is important because some snaps have broad permissions and really does require this mode.
The problem is transition between the two configurations. While technically easy to perform, it must be done due to one of two different reasons:
- Device added or removed to the system This is currently handled by udev and snap-device-helper shell script which adds or removes entries to an existing confined device cgroup.
- Interface connected or disconnected. This is handled by snapd and indirectly, by udev that we “trigger” and “settle”.
Note that neither of those can change a device cgroup from confined to unconfined.
In my eyes, we need a pair of new components. The first is a per snap app/hook file that list devices to be tagged. This is something we can ask udev to generate for us based on udev device database and our tagging rules. We can effectively re-create this each time something changes (either the tagging rules or the actual devices). The second is a tool that reads that file and re-configures a cgroup to either confined or unconfined mode. This is relatively straightforward.
Each time interface connection relating to udev occurs we must invoke that tool.
Each time udev device is added or removed we must invoke that tool.
In other words, we need snap-update-ns equivalent for device cgroups.