Special bind mount for snap instances, including classic confinement!

Hello

As we are working on snap instances, where a single snap may be installed multiple times under different names, possibly tracking different channels and in general having different revisions active, we face an important issue in how many classically confined snaps are actually constructed.

Today a classically confined snap may use compiled C code and set the prefix to /snap/realname/current/usr to effectively get many C programs to do the right thing and get their files from /snap/realname/current (which is a symlink) /usr.

If on a given system that is instantiated as instancename it will appear as /snap/instancename/current/usr but the hard-coded paths still refer to realname.

The proposed solution is to put classically confined snaps in a new mount namespace and provide them with a recursive bind mount from /snap/instancename/ to /snap/realname. That is, whatever the instance is will hide the real snap (non-instantiated) mount point but only from the point of view of that snap’s process.

How can we do this? I think we can do this as follows:

  • unshare the mount namespace
  • make /snap a mount point with slave event propagation (see below).
  • create a bind mount from /snap/instancename to /snap/realname

This mount namespace would not be preserved anywhere as it would not need any updates for individual processes. The slave event propagation refers to https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt where a given mount namespace receives mount events (that is mounts and unmounts) from another namespace when those mount events belong to a particular tree (a mount point and anything below that is not overridden by another mount point).

That’s the current proposal, I will prepare some exploratory PR for this shortly.

3 Likes

@zyga-snapd Thanks for the nice summary. That would certainly solve the issue I think.

There’s one minor note from today’s call which is we want /snap/realname to always exist whenever we have some /snap/realname_suffix parallel installation. That should be easy to ensure internally in the installation logic.

Also worth noting that it is possible for the realname snap to be installed in the system both with and without a suffix, at the same itme. In other words, a realname installation can coexist with a realname_suffix one. I don’t think that’ll create further issues, but just something worth keeping in mind.

cc @mborzecki

I guess if you do this, you could also make sure classic snaps run in a mount namespace that has /snap in it?

Well, that’s different. We’d have to create mount point for /snap and unless we are happy with changing the whole root filesystem or until we can start using overlays I don’t think that’s easy. Unless you have a way to, that is, I may be wrong.