]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lsm: apparmor: allow to change mount propagation 4295/head
authorAlexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Fri, 31 Mar 2023 11:25:37 +0000 (13:25 +0200)
committerAlexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Fri, 31 Mar 2023 12:30:19 +0000 (14:30 +0200)
Long story behind this. Many years ago, Stéphane Graber
discovered an issue with apparmor mount rules.

Since
https://github.com/lxc/lxc/commit/7f2b13275daf68b173474900b1ce2c04105da33f
commit ("apparmor: Update mount states handling") it was prohibited
to change mount propagation flags, just because adding rules which
allow mount propagation user inside the container gets an ability
to mount everything [1].

Now with modern systemd versions this problem become more critical than
before. For instance, ArchLinux containers fail to start without
nesting apparmor profile enabled (because nesting profile effectively
just allow all mounts). Of course, that's a security issue.

We've also enabled sharing on the container rootfs:
https://github.com/lxc/lxc/pull/4229

Now for many workloads it's needed to change propagation flag to
private (see https://github.com/canonical/craft-parts/pull/400).

Issue:
$ lxc-start -F archlinux-test

systemd 253-1-arch running in system mode (+PAM +AUDIT -SELINUX -APPARMOR -IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP -SYSVINIT default-hierarchy=unified)
Detected virtualization lxc.
Detected architecture x86-64.

Welcome to Arch Linux!

bpf-lsm: BPF LSM hook not enabled in the kernel, BPF LSM not supported
Failed to remount root directory as MS_SLAVE: Permission denied
(sd-gens) failed with exit status 1.
[!!!!!!] Failed to start up manager.
Exiting PID 1...

Workaround (unsafe):
$ lxc-start -s lxc.apparmor.allow_nesting=1 -s lxc.apparmor.profile=generated -F arch-test

John Johansen (Apparmor maintainer) and LXD team worked on fix [2].
It was merged to stable AppArmor 3.0 and 3.1 branches already.
There is no stable AppArmor version tag for that, but I think it will
be in the AppArmor version 3.0.10.

See also:
[1] https://bugs.launchpad.net/apparmor/+bug/1597017
[2] https://gitlab.com/apparmor/apparmor/-/merge_requests/333

Fixes: #4280
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
config/apparmor/abstractions/container-base
config/apparmor/abstractions/container-base.in
src/lxc/lsm/apparmor.c

index 0774765594ef05ae2f57a698eb2c8ae708dfe135..69bf6c3b56a0e45bb80e7d07ca8204d66d107732 100644 (file)
   deny /sys/kernel/debug/{,**} rwklx,
 
   # allow paths to be made slave, shared, private or unbindable
-  # FIXME: This currently doesn't work due to the apparmor parser treating those as allowing all mounts.
-#  mount options=(rw,make-slave) -> **,
-#  mount options=(rw,make-rslave) -> **,
-#  mount options=(rw,make-shared) -> **,
-#  mount options=(rw,make-rshared) -> **,
-#  mount options=(rw,make-private) -> **,
-#  mount options=(rw,make-rprivate) -> **,
-#  mount options=(rw,make-unbindable) -> **,
-#  mount options=(rw,make-runbindable) -> **,
+  mount options=(rw,make-slave) -> **,
+  mount options=(rw,make-rslave) -> **,
+  mount options=(rw,make-shared) -> **,
+  mount options=(rw,make-rshared) -> **,
+  mount options=(rw,make-private) -> **,
+  mount options=(rw,make-rprivate) -> **,
+  mount options=(rw,make-unbindable) -> **,
+  mount options=(rw,make-runbindable) -> **,
 
   # allow bind-mounts of anything except /proc, /sys and /dev
   mount options=(rw,bind) /[^spd]*{,/**},
index 2606fb64c67c2f7e7829c6cc88b9fc86d329928a..2ca4e2f7bbf1c3a0b3eb9c2f21a6afe55d50efa5 100644 (file)
   deny /sys/kernel/debug/{,**} rwklx,
 
   # allow paths to be made slave, shared, private or unbindable
-  # FIXME: This currently doesn't work due to the apparmor parser treating those as allowing all mounts.
-#  mount options=(rw,make-slave) -> **,
-#  mount options=(rw,make-rslave) -> **,
-#  mount options=(rw,make-shared) -> **,
-#  mount options=(rw,make-rshared) -> **,
-#  mount options=(rw,make-private) -> **,
-#  mount options=(rw,make-rprivate) -> **,
-#  mount options=(rw,make-unbindable) -> **,
-#  mount options=(rw,make-runbindable) -> **,
+  mount options=(rw,make-slave) -> **,
+  mount options=(rw,make-rslave) -> **,
+  mount options=(rw,make-shared) -> **,
+  mount options=(rw,make-rshared) -> **,
+  mount options=(rw,make-private) -> **,
+  mount options=(rw,make-rprivate) -> **,
+  mount options=(rw,make-unbindable) -> **,
+  mount options=(rw,make-runbindable) -> **,
 
   # allow bind-mounts of anything except /proc, /sys and /dev
   mount options=(rw,bind) /[^spd]*{,/**},
index 685d3b9ef7735d36b314fc5b948b58c35ff9631c..ba486c63d71456ef7bc47a15bb5b06a0bc25bece 100644 (file)
@@ -113,25 +113,14 @@ static const char AA_PROFILE_BASE[] =
 "  deny /sys/kernel/debug/{,**} rwklx,\n"
 "\n"
 "  # allow paths to be made dependent, shared, private or unbindable\n"
-"  # TODO: This currently doesn't work due to the apparmor parser treating those as allowing all mounts.\n"
-"#  mount options=(rw,make-slave) -> **,\n"
-"#  mount options=(rw,make-rslave) -> **,\n"
-"#  mount options=(rw,make-shared) -> **,\n"
-"#  mount options=(rw,make-rshared) -> **,\n"
-"#  mount options=(rw,make-private) -> **,\n"
-"#  mount options=(rw,make-rprivate) -> **,\n"
-"#  mount options=(rw,make-unbindable) -> **,\n"
-"#  mount options=(rw,make-runbindable) -> **,\n"
-"\n"
-"# Allow limited modification of mount propagation\n"
-"  mount options=(rw,make-slave) -> /,\n"
-"  mount options=(rw,make-rslave) -> /,\n"
-"  mount options=(rw,make-shared) -> /,\n"
-"  mount options=(rw,make-rshared) -> /,\n"
-"  mount options=(rw,make-private) -> /,\n"
-"  mount options=(rw,make-rprivate) -> /,\n"
-"  mount options=(rw,make-unbindable) -> /,\n"
-"  mount options=(rw,make-runbindable) -> /,\n"
+"  mount options=(rw,make-slave) -> **,\n"
+"  mount options=(rw,make-rslave) -> **,\n"
+"  mount options=(rw,make-shared) -> **,\n"
+"  mount options=(rw,make-rshared) -> **,\n"
+"  mount options=(rw,make-private) -> **,\n"
+"  mount options=(rw,make-rprivate) -> **,\n"
+"  mount options=(rw,make-unbindable) -> **,\n"
+"  mount options=(rw,make-runbindable) -> **,\n"
 "\n"
 "  # allow bind-mounts of anything except /proc, /sys and /dev\n"
 "  mount options=(rw,bind) /[^spd]*{,/**},\n"