Interfaces in classic snaps

Right now the store is rejecting classic snaps that have any plugs or slots. Is there a reason for us to be still doing that? Given the semantics of interfaces, I think it makes sense to allow classic snaps to expose them as well, as the functionality that they offer is much richer than what classic snaps enable.

Can anyone think of reasons why this might be a problem?

If we can’t think of any major problems, can we please give it a shot?

We’d have to differentiate interfaces that mean something in classic confinement from the rest. While having interfaces be there and just be a no-op is fine technically it can confuse people into thinking they need them or that they serve some function.

Once we have interfaces that affect classic confinement then I agree we should just allow those to be used.

Replying to myself I now see that there are in fact existing interfaces that do have a meaning in classic: GPIO (using the systemd backend) or firewall-control (using the kmod backend)

Historically, we didn’t care if someone specified interfaces because it was most often a no-op. The check was added (and made sense since it was (again, historically) a no-op) because something was broken (snap install?) when you specified interfaces with classic. If that is resolved now, I’m happy to update the review tools.

Before I do that though I want to ask, if it is only fixed in recent snapd, do we care that classic snaps might be broken because a system may have an older core installed?

I’d need to check but I think there’s still some work to be done to make sure seccomp and appermor are not behaving silly there.

@zyga-snapd Indeed, we need to make sure that those specific profiles are not generated for those snaps.

In thinking about this a little, perhaps it makes sense to only enable the backends that can reasonably work with classic when using classic confinement. For example, apparmor, seccomp and udev should all be disabled with classic, but, like you said, kmod should be enabled, and systemd. I think dbus should (perhaps?) be enabled too (but snaps could always copy files into place if desired (though that is a bit weird)).

Something expecting the udev backend to do its work would break if it’s not working, wouldn’t it?

Well, that depends on what the rule is doing. For the vast majority (but not all of them) we just do udev tagging so tagged devices can be placed in a device cgroup. I don’t expect those would break if the tagging went away as the application usually does the lookup by itself and tagging is just a mechanism to make sure such device nodes are accessible. For things like network manager or modem manager, that essentially dump KBs of udev rules the actual rules are essential for the runtime behavior of the application as they set various identifying attributes and run helper programs. I think it’s a per-interface behavior that we are after.

I suspect explicitly want to omit the device cgroup because if we used it then the snap would only be able to see the devices that were assigned to it, which is a form of confinement and not what the snap would expect.

As for the snap-provided udev rules, for the same reason @niemeyer gave on the dbus backend and it continuing to provide its rules, it seems we would want to continue to provide the udev rules.

Thus far I think we’ve said with strict confinement, the backends wrt interface connections should:

  • skip: apparmor rules, seccomp rules, udev tagging for device cgroup
  • continue: dbus rules, non-snappy-tag udev rules, kmod, systemd

Whoops, I of course meant “Thus far I think we’ve said with classic confinement”

(moving a duplicated topic here)

At the moment store review will flag out slot declaration inside classic snap. This should be probably softened as there are genuine cases where this is the right way forward.
We can mix classic and strictly confined snaps on one device, this can easily lead to cases where one might need to declare slot(s) in classic snap to allow connection. Typical use case would be classic snap exposing d-bus interface which could be also consumed by strictly confined snaps. In this case we need slot to which plug declared in strictly confined snap can be connected.

not sure if this is mentioned here, but one of the use cases our partner hit was case where they use classic snap to access hw ( on classic system it’s tricky to access hw for which slot would be normally defined in gadget snap) At the same time they have client(s) accessing this classic service over dbus. For client(s) they are happy to run them strictly confined. So they need to define dbus slot in classic snap, so it can be connected to strictly confined one. This seems to me like perfectly reasonable use case. Using one classic snap should not force rest of the snaps downstream to be also classic……

@pstolowski I’m moving this into upcoming and putting in the roadmap. This sounds like a good candidate for us to tackle once we’re done with the current work on interfaces hooks, as there would be even more value in supporting these in classic snaps.

1 Like