Base runtime freedesktop-sdk-runtime-19-08


#10

I performed a review of revision 12 of the snap and can say that:

  • the permissions/ownership of the files in the snap are fine
  • the following are missing from the snap that snap-confine won’t mkdir (from sc_populate_mount_ns() in mount_support.c)
    • empty mnt (optional, but best to include)
    • empty var/lib/extrausers (optional)
  • there is a lot in the base that is not represented in the default template or interfaces. Eg (listing just a few representative items):
    • kerberos binaries
    • usr/bin/lz*
    • usr/bin/sndfile-*
    • usr/bin/tiff*

I also noted that the snap has a lot in /etc which is just going to be mounted over.

It isn’t clear to me if everything in the snap is expected in the runtime (I suspect not since it also includes things like pam and mkfs utilities) so it seems that the snap needs to be cleaned up to only ship the things that it requires (this would also make it much smaller). Once that is done, we can revisit what is needed to proceed. @pedronis, can you also weigh in?


#11

We can change that.

I did not try to publish yet the SDK part which is needed for building against. I have seen that the images used were hard coded. The first goal however is to be able to provide applications built with BuildStream. So this is not needed to use snapcraft to build application. But I think we should we should get snapcraft to be able to build on top of the Freedesktop SDK.

I will add those directories. Is there documentation (or commented source code) related to those? Are we suppose to read something from there?

/etc being mounted over is actually a tricky issue. One issue with it for example is that fontconfig configuration is taken from the system, but system fonts do not seem to be mounted.

I expect we will have other issues like that. Flatpak selectively binds files like /etc/resolv.conf, so we never had to worry about where the configuration files go.

I am planning to change the path to /usr/etc for files that should be read from the Freedesktop SDK runtime rather than the system. Though for fontconfig, I need to get a file from /etc from flatpak that tells me where the system fonts have been mounted, so I am expecting some work there.

Would file from /usr/bin not be allowed to run with snap-confine? I have already noticed that bash has some issue, so I added dash. But I thought this was only needed at startup. Running lzip for example seem to work. Is snap-confine relaxed when running --shell?

I suppose for pam and mkfs was because we need the libraries and we did not filter out the binaries. We will fix that.


#12

I suspect you can ignore the extrausers stuff. It is used by Ubuntu Core systems to allow new users to be added to a system where /etc/passwd is read only. This is only really important for a base snap that is being used to boot a system.

I don’t think it is relevant to a base snap that is purely being used as an application runtime like what you’re proposing.

For applications that plug the desktop interface, the following will be mounted in from the host system:

  • /usr/share/fonts
  • /usr/local/share/fonts
  • /var/cache/fontconfig

So the system fonts.conf is usually good enough, unless your fontconfig is old enough not to recognise the translation attributes/elements found on modern systems. Related to this, if you’re shipping any fonts in the above directories, they will likely be shadowed by any applications using your base.


#13

Thank you for solving that mystery. That was not very obvious.


#14

Our current bases ship with non-empty /etc, also because they are meant for use as bootable bases for core. I’m not sure if we should enforce empty /etc for non bootable bases (bases not intended for booting) for clarity or not, or if achieving that is too annoying for the build processes of bases.

Either way given the current mechanics /etc will be ignored/mounted over. If there’s really something needed from there we have a problem.


#15

It is hard to know if there are files needed. If there are bugs reported related to it, we will move the needed ones to /usr/etc. But most likely most of the ones mounted should be fine.


#16

The list is being built up (prompted by this request). The current list is here: https://git.launchpad.net/review-tools/tree/reviewtools/sr_common.py#n279 (and yes, var/lib/extrausers was later deemed unneeded).


#17

Note that if you ship them in /usr/etc, you can then use the layouts feature to put them in /etc (eg, via a bind mount) if you don’t want to modify code to use paths in /usr/etc.


#18

Well, the thing is there is security policy that allows use of specific binaries in /usr/bin. Since the core snap doesn’t include the ones I mentioned, security rules aren’t present for allowing use of them. If you need to ship binaries in /usr/bin, /bin, etc that aren’t also present in the core snap, then we need to design a way to expose them to the snap (fyi @pedronis). That said, I’m puzzled that you said it seemed to work. How did you test this?


#19

Yeah, I didn’t mean to imply it would be rejected but more to point out that since it has stuff, it isn’t going to be used. Clean is clearer though, so happy to update the review criteria as needed.


#20

I see --dangerous implies --dev-mode. Is there a way to force install something without disabling security confinment?


#21

I have misread the documentation. It is devmode that implies dangerous.

OK, so I have made an app that contains just a script. And snap info --verbose says it has confinement on. The script only contains a call to /usr/bin/lzip -h. And it works. So obviously confinement does not disallow applications to call lzip.


#22

while this is true, you can not be sure that all bases (there will be more than core and core18 in the future) actually ship the binary …


#23

I have found out that my installation on Debian does not have full confinement. Only devmode. So that might be the issue why I can call lzip.


#24

That would explain it, yes.


#25

@valentind - it sounds like you are working on trying to make the runtime smaller. Is this so it will run with the default template or will it still have things outside of the default template that the snap should have access to? If the latter, can you provide that list? (cc @pedronis - this is sounding like we will need a concept of base snap security policy templates…)


#26

Not much will be removed. I think the last thing I have to remove are some gettext utilities.

The list of executable needed might change from one release to another. I suggest, in order to make snap-confine to work with other bases, to allow execution for the following:

  • {/usr,}/bin/*
  • {/usr,}/sbin/*
  • {/usr,}/libexec/**
  • {/usr,}/lib{,32,64,x32}/**

For the case of the Freedesktop SDK, we need only:

  • /usr/bin/*
  • /usr/libexec/**
  • /usr/lib/**

The alternative can be that we provide the exact list of paths in the metadata to generate the apparmor file.


#27

@jdstrand is off for a little while, but I let him comment on this when he is back. It’s unlikely we can have blank permissions like that tough.


#28

These accesses are indeed quite broad. @pedronis - we need to think through what we want confinement to look like for base snaps. I’ll list a few random thoughts to seed the conversation and then provide my current view.

In a lot of ways, the broad access makes sense since in a sense a base snap is like a content snap and we allow this sort of access with content snaps. In terms of security, there is tremendous trust in the base snap publisher for snaps that use the base and we have seccomp, apparmor capabilities, etc, etc in place (just like we do with content snaps and for people that stage-packages), but apparmor file access could provide some guardrails here. We will definitely want to continue to disallow file caps, setuid, etc regardless of how we move forward.

Base snaps overlap with content snaps but are different in that they are the base runtime and limiting the access has benefits beyond security (as well as maintenance costs). The apparmor policies could assist with declaring what is meant to be there and supported. The default apparmor template was always meant to expose the bits of the core snap that would be meaningful as a runtime of snaps and no more, which suggests we should do the same with base snaps. Where it breaks down is that apparmor is imperfect for this since apparmor won’t detect if something that was allowed is removed and it doesn’t help with cross-distro with forced devmode (indeed, we use the same template for core{,16} and core18 even though core18 doesn’t ship things allowed in the template; the fact that we are using the same template is AFAIK not by design, is evolutionary and arguably a mistake).

I’m a bit concerned about exposing all of /usr/bin/, etc since some of those binaries are going to be poking around in /etc and I foresee compatibility issues with the shared-/etc-with-the-host and binaries in the base snap. If the binaries can be curated and enumerated, the enumeration process can provide a form of sanity check to the whole process. We already have processes for reviewing new file accesses in the template/interfaces, so this same process could be extended to base snap policy which is a natural forum to discuss how things work, might break, etc.

Finally, I also have concerns with how base snaps will interact with implicit interfaces. Eg, do we really want to go in the direction of having each interface be the superset of accesses for all base snaps? I suspect not, and I’m a little uncomfortable in the direction of https://github.com/snapcore/snapd/pull/7073 in this regard: it is extending the opengl apparmor policy to account for paths provided by a particular base snap.

I admit that I didn’t bring all this up when the concept of base snaps was first introduced (since no one was using them), but now that people are actively creating new ones and they are being suggested for various uses, I feel like we need to press pause for a moment and think through how this should work more. I’m feeling like a better path forward is:

  • for each base snap where the default template is not sufficient, provide an alternative base snap template or append base-specific policy to the current template (whichever is more appropriate)
  • for each base snap where interface policy is not sufficient, provide an alternative base snap interface policy or append base-specific policy to the interface policy (whichever is more appropriate. For the opengl PR, this would mean breaking out the base snap policy into a separate snippet that is only added when the base in question is in use).

This adds implementation complexity, but in addition to the aforementioned guardrails, it is tidier in many ways, helps with policy auditing and helps prevent inflated policy. I suspect it would help with longterm maintenance as well since would accommodate situations where, for example, we know that an access is ok in base snap ‘foo’, but not ‘bar’, because ‘foo’ is hardened in some way where ‘bar’ is not.


#29

We will be fine providing either a policy template or fragment along with our runtime. Just say when there is something to test.