The plan is to have everything upstream, but I don’t know what kernel Buster will use.
I just tested this in an up to date sid with 4.12 kernel. I did:
$ sudo apt-get install snapd
$ sudo snap install hello-world
$ /snap/bin/hello-world.evil
Hello Evil World!
This example demonstrates the app confinement
You should see a permission denied error next
If you see this line the confinement is not working correctly, please file a bug
That tested snapd with apparmor disabled. To enable apparmor, adjust /etc/default/grub to have:
GRUB_CMDLINE_LINUX_DEFAULT="quiet apparmor=1 security=apparmor"
then do:
$ sudo update-grub
$ sudo reboot
<login again>
$ sudo aa-status
$ sudo aa-status
apparmor module is loaded.
0 profiles are loaded.
0 profiles are in enforce mode.
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
$ snap --version
snap 2.27.1-1
snapd 2.27.1-1
series 16
debian unknown
kernel 4.12.0-1-amd64
$ hello-world.evil
Hello Evil World!
This example demonstrates the app confinement
You should see a permission denied error next
If you see this line the confinement is not working correctly, please file a bug
I found this curious-- the snap-confine profile was not loaded. I found that ‘apt-get install snapd’ installs an empty profile in /etc/apparmor.d/usr.lib.snapd.snap-confine.real
$ ls -l /etc/apparmor.d/usr.lib.snapd.snap-confine.real
-rw-r--r-- 1 root root 0 Aug 14 04:53 /etc/apparmor.d/usr.lib.snapd.snap-confine.real
If I generate the profile from git checkout release/2.27
(I used ./configure --prefix=/usr --libexecdir=/usr/lib/snapd --enable-nvidia-ubuntu --enable-static-libcap --enable-static-libapparmor --enable-static-libseccomp
) and copy it over to the Debian machine:
$ sudo cp ./snap-confine.apparmor /etc/apparmor.d/usr.lib.snapd.snap-confine.real
$ sudo apparmor_parser -r /etc/apparmor.d/usr.lib.snapd.snap-confine.real
$ sudo aa-status
apparmor module is loaded.
2 profiles are loaded.
2 profiles are in enforce mode.
/usr/lib/snapd/snap-confine
/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
$ sudo snap install hello-world
...
$ /snap/bin/hello-world.evil
/usr/lib/snapd/snap-confine: error while loading shared libraries: libcap.so.2: cannot open shared object file: No such file or directory
$ grep DEN /var/log/syslog
Aug 16 07:22:48 debian-sid-amd64 kernel: audit: type=1400 audit(1502886168.383:7): apparmor="DENIED" operation="open" profile="/usr/lib/snapd/snap-confine" name="/lib/x86_64-linux-gnu/libcap.so.2.25" pid=2627 comm="snap-confine" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Ok, so snap-confine is confined, but it is missing a rule needed to run. Note that snapd didn’t load the hello-world profiles:
$ sudo aa-status
apparmor module is loaded.
2 profiles are loaded.
2 profiles are in enforce mode.
/usr/lib/snapd/snap-confine
/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
If I add this rule to the snap-confine profile:
/lib/@{multiarch}/libcap.so* mr,
Then reload the profile and try hello-world.evil, I can reproduce the Debian bug:
$ sudo apparmor_parser -r /etc/apparmor.d/usr.lib.snapd.snap-confine.real
$ /snap/bin/hello-world.evil
execv failed: Permission denied
$ sudo grep DEN /var/log/syslog | tail -1
Aug 16 07:25:17 debian-sid-amd64 kernel: [ 1351.246752] audit: type=1400 audit(1502886317.157:10): apparmor="DENIED" operation="exec" profile="/usr/lib/snapd/snap-confine" name="/usr/lib/snapd/snap-exec" pid=2665 comm="snap-confine" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0
Ok, if I build 2.27 like we do on Ubuntu, and copy it all over to the sid machine, then snapd still won’t load the hello-world profiles:
$ sudo aa-status
apparmor module is loaded.
2 profiles are loaded.
2 profiles are in enforce mode.
/usr/lib/snapd/snap-confine
/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
This is because snapd forces devmode (see requiredApparmorFeatures in release/release.go). If I booted a kernel with all the required features, I would expect things to start to work.
I believe there are several bugs:
- the snap-confine profile is empty
- the snap-confine profile is missing a rule for libcap (on Debian we aren’t using --enable-static-libcap like in Ubuntu)
- the snap-exec denial has to do with the fact that snapd is built with --disable-apparmor. snap-confine is not performing a profile transition to hello-world.evil, so snap-confine continues to stay in its profile where snap-exec is not allowed
- snapd-design: when booting a kernel without the required apparmor feature set, the system is put in devmode and apparmor profiles are not loaded
Detangling this would require:
- ship a proper apparmor profile for snap-confine
- use --enable-static-libcap
- conditionally add a rule to snap-confine’s profile:
/usr/lib/snapd/snap-exec uxr,
With the above, one should be able to freely enable/disable apparmor via kernel command line, and when booting a kernel with the supported feature set, the profiles will be generated. Note that point ‘3’ needs a little design since snapd will be updating snap-confine’s profile dynamically.
Once all that is done, we could revisit the required apparmor feature set, but note this is an explicit snapd design decision that went through extensive review with @niemeyer, @mvo, @zyga-snapd and myself.