I was surprised to hear that we were no longer enforcing that snapd must be started before daemons. The sandbox was specifically designed with this requirement such that apparmor was loaded before snapd, snapd updated security profiles (seccomp or apparmor (reloading as necessary)) and only then were services allowed to start. It was understood that non-daemon commands necessarily would only be run from a login session (eg, lightdm, console, etc) and that those should start after snapd (I say âshouldâ because I didnât think we had anything in practice that said login session must be after snapd and we instead relied on the fact that this happened under normal boot conditions (a bug in and of itself), except on Touch where we specifically adjusted the lightdm service to start after apparmor).
Anyway, I think the BPF approach is quite sane in general, but it doesnât really solve the whole problem. Historically we relied on apparmor to have to start before any snap commands because the policy needed to be loaded into the kernel before the command started. AppArmor conveniently has profile âreloadâ functionality where you can change the profile of a running process that was started under the same profile (ie, apparmor_parser -r) and so snapd coming along at some later point in time to reload the apparmor didnât show up as a problem (though, that is not correct). Importantly, seccomp does not have reload functionality (due to upstream seccomp design) and the profile must be in place before the command starts. The BPF approach alone does make sure that the profile is in place in such a way that snap-confine wonât die, but it does not guarantee that the policy is correct for the version of snapd that is actually running. To me, it is vitally important that the security policy that commands run under is predictable, robust and deterministic so that there is never a question of âis this now running under the old, pre-revert policy or the new reverted policy?â. The BPF approach alone does not solve that-- it only solves the problem of âcan I launch the command under policy that snapd compiled at some point in the past?â. This is a worthy problem to solve in and of itself of course, but commands should only be allowed to run under the policy that the version of the running snapd generated.
As such, I strongly feel something along the lines of the medium term approach is required, regardless of if we pursue the BPF approach or not.
In terms of the long term approach, I think we should look at apparmor again-- the parser is able to parse all old policy and introspect the kernel for what is supportable. snapd/the seccomp parser BPF compilation tool would do exactly the same. It is in a position to introspect the kernel and can recompile policy to disk as necessary. Determining when that is necessary and the implementation details is TBD, but the seccomp parser is certainly in a position to look at existing policy, update the binary BPF, look at the kernel, etc and make intelligent decisions.