Find out which slots are needed for a snap

There is a snap for tmux in the snap store. When building for a new version of tmux, the snap does not work once strict confinement is set.

  1. When building and installing the new snap with sudo snap install tmux-non-dead_3.1b_multi.snap --classic --dangerous, there is an error message stating that the snap need classic confinement.
  2. The snap probably fall in the category “terminal emulators, multiplexers and shells” in the review guidelines

On the other hand, the tmux source code seems to indicate that it is able to be run with lower privileges with pledge(2). Perhaps there is a way to determine which slots that is needed to run tmux without resorting to go full on --classic? Although I appreciate that the security models for pledge and snap might not be in any way similar.

So the question is: is there a good way to see which slots that are needed? Without resorting to enable all the slots and then start to disable, rebuild and test?

I don’t specifically know in this case, but when I need to sort out interfaces, I will often put the snap I’m developing on in devmode and use snappy-debug to provide suggestions based on the logs.

snap install tmux*.snap --devmode
snap install snappy-debug

snappy-debug

# run tmux
tmux ...

Note that pledge() is not a Linux system call, so it is unavailable. AIUI, it is not terribly far away conceptually from our sandbox model in that some things are default allowed but with restrictions (akin to our default template) and others things can be declared with ‘promises’ that are not dissimilar to what snap interfaces achieve.

The thing is, for a general purpose tmux you actually don’t want it confined since you want to be able to do anything, just like with a shell.

For a snap to ship a restricted tmux, the tmux code itself needs no special permissions, but it must use the libutempter library which requires the utempter setgid helper which is not shipped in base snaps so must be shipped by the snap, which isn’t allowed to ship setgid binaries (for many reasons, not least of which, the gid in the snap won’t be the same gid across all distributions). Furthermore, as a snap under strict confinement, there are a number of challenges related to snaps running other snaps or arbitrary commands (as mentioned above). Eg, it runs in its own mount namespace, under its own seccomp profile (and syscall filters can only get more strict), runs in snap-specific cgroups and under its own snap-specific apparmor profile (which is somewhat easier to deal with since apparmor supports exec transitions). I have explored what a special tmux (or screen) interface might look like on several occasions but it is quite problematic without tmux understanding external sandboxing concepts (some of which might need to be invented to be performant) or exposing arcane sandboxing options to users.

IMO (and I’ve mentioned this https://forum.snapcraft.io/t/attempting-to-snap-screen/4917), Ubuntu Core should ship tmux and/or screen in the image so shell users have access to it. Classic distro users either use distro packaging or a classic snap. It would not be impossible to introduce an interface that when plugged would make the snap behave like a classic snap, but this obviously doesn’t address the request here for some confinement and completely bypasses the current design of ‘classic snaps not allowed on Ubuntu Core’.

That is the official answer. As a user/tinkerer, if you have a UC device, it should be possible to unpack the tmux and libutempter0 debs on a UC device (eg, Ubuntu 18.04 LTS debs on a UC18 device) and make adjustments to the tmux invocation so it works. Then one could write an apparmor profile in /etc/apparmor.d for tmux to restrict it to site requirements (and if UC shipped it by default, the admin could write an apparmor profile for it). This is clearly unsupported, outside of spec and inelegant.

1 Like