Cannot open path of the current working directory: Permission denied bis

well, having an @ and dots in a username is definitely not POSIX standard/default :slight_smile:

1 Like

Is there a specific denial that appears when you try to run codium? Try running dmesg |grep DENIED.

Yes, we know that, but we unified authentication for Linux / Windows and services. We don’t face any limitation (other than that one, if it’s related)

Yes, there are some DENIED lines

[ 3312.151969] audit: type=1400 audit(1644571146.193:127): apparmor="DENIED" operation="sendmsg" profile="/usr/lib/snapd/snap-confine" pid=11138 comm="snap-confine" laddr=162.38.80.54 lport=895 faddr=162.38.151.4 fport=2049 family="inet" sock_type="stream" protocol=6 requested_mask="send" denied_mask="send"

Any workaround ? I continue to randomly get those errors and don’t know how to workaround. Sometimes, I can rm -rf /snap/codium and it solve it for a time. But now I can’t remove this directory because it’s readonly…

Good news everyone ! Firefox package installed with apt results in installing firefox snap package. As the apparmor problem is identified, how to fix this one time for all ?

From Snaps and NFS /home

$ cat /etc/apparmor.d/tunables/home | grep -v '#'

@{HOME}=@{HOMEDIRS}/*/ /root/

@{HOMEDIRS}=/home/

include <tunables/home.d>
 
$ cat /etc/apparmor.d/tunables/home.d/* | grep -v '#'

@{HOMEDIRS}+=/home/

So this doesn’t help. When I start firefox I get

May  5 15:35:05 jammy kernel: [ 2783.608909] audit: type=1400 audit(1651757705.831:189): apparmor="DENIED" operation="sendmsg" profile="/usr/lib/snapd/snap-confine" pid=12752 comm="snap-confine" laddr=162.38.80.15 lport=898 faddr=162.38.151.4 fport=2049 family="inet" sock_type="stream" protocol=6 requested_mask="send" denied_mask="send"

Does your NFS service (I presume your home folders are on NFS shares by previous messages here, if I’m wrong, please forgive and correct me) use any of the NFS *_squash rules? e.g. root_squash

Hi @eoli3n! Your /home configuration in AppArmor is correct. I guess that the 168.38.x.x addresses we see in your apparmor denial messages are the addresses you are using in your NFS network?

I’m not sure why snap-confine is attempting to access the NFS directly; I would assume that all the NFS implementation should happen in the kernel and not in the client process (but I never used NFS before, so if I’m wrong please don’t hesitate to correct me).

I guess I need to do some more study on NFS to understand why snap-confine is attempting to access the network (it shouldn’t!). I’ll get back to you tomorrow :slight_smile:

I assume snap-confine’s current working directory is within HOME and hence it tries to read from there at some point and then gets this error. This is tracked in https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1662552 and from what I can see snapd should be trying to auto-detect NFS mounted $HOME by inspecting the mount table etc (see https://github.com/snapcore/snapd/blob/master/osutil/nfs_linux.go#L29) - so perhaps the output from /proc/self/mountinfo or /etc/fstab are not what snapd is expecting?

@eoli3n could you post the output from:

grep home /proc/self/mountinfo

and

grep home /etc/fstab

Thanks

So, @lucyllewy I asked to the NFS guy for the export line, waiting for his answer. Can I see this from the client ?

@mardy yes this is our network, 162.38.80.X is the client, 162.38.151.X is the server.

@alexmurray

root@jammy:~# grep home /proc/self/mountinfo
2118 29 0:70 / /home rw,relatime shared:915 - autofs /etc/auto.master.d/home rw,fd=7,pgrp=5756,timeout=300,minproto=5,maxproto=5,indirect,pipe_ino=41032
1080 2118 0:72 / /home/p00000012366 rw,relatime shared:582 - nfs4 nfsserver:/home/p00000012366 rw,vers=4.2,rsize=8192,wsize=8192,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=162.38.80.15,local_lock=none,addr=162.38.151.4

As you see we use autofs to mount homes, so no line in the fstab.

$ cat /etc/auto.master.d/home
*       -fstype=nfs,vers=4,rw,soft,rsize=8192,wsize=8192        nfsserver:/home/&

Maybe the problem is related to the fact that our home directories are not map on the uid field ? My account is “user.name@domain.fr” but my home directory is “p000000xxxxx”.

This is what I do in sssd config

$ grep ldap_user_name /etc/sssd/sssd.conf
ldap_user_name = mail

Hi! Can you please check in the output of journalctl -u snapd if you can find a line like this:

snapd enabled NFS support, additional implicit network permissions granted

?

Yes the line can be found

mai 05 14:48:51 jammy systemd[1]: Starting Snap Daemon...
mai 05 14:48:52 jammy snapd[694]: AppArmor status: apparmor is enabled and all features are available
mai 05 14:48:52 jammy snapd[694]: overlord.go:263: Acquiring state lock file
mai 05 14:48:52 jammy snapd[694]: overlord.go:268: Acquired state lock file
mai 05 14:48:53 jammy snapd[694]: daemon.go:247: started snapd/2.55.3+22.04 (series 16; classic) ubuntu/22.04 (amd64) linux/5.15.0-27-generic.
mai 05 14:48:53 jammy snapd[694]: daemon.go:340: adjusting startup timeout by 1m30s (pessimistic estimate of 30s plus 5s per snap)
mai 05 14:48:53 jammy systemd[1]: Started Snap Daemon.
mai 05 21:38:54 jammy snapd[694]: storehelpers.go:721: cannot refresh: snap has no updates available: "bare", "cmake", "core", "core20", "dust", "gnome-3-38-2004", "gtk-common-themes", "pdftk", "snap-store", "snapd", "snapd-desktop-int>
mai 05 21:39:16 jammy snapd[694]: storehelpers.go:721: cannot refresh snap "firefox": snap has no updates available
mai 06 05:53:53 jammy snapd[694]: storehelpers.go:721: cannot refresh: snap has no updates available: "bare", "cmake", "core", "core20", "dust", "firefox", "gnome-3-38-2004", "pdftk", "snap-store", "snapd", "snapd-desktop-integration"
mai 06 05:54:01 jammy snapd[694]: storehelpers.go:721: cannot refresh snap "gtk-common-themes": snap has no updates available
mai 06 06:09:57 jammy snapd[694]: main.go:155: Exiting on terminated signal.
mai 06 06:09:57 jammy systemd[1]: Stopping Snap Daemon...
mai 06 06:09:57 jammy snapd[694]: overlord.go:504: Released state lock file
mai 06 06:09:57 jammy systemd[1]: snapd.service: Deactivated successfully.
mai 06 06:09:57 jammy systemd[1]: Stopped Snap Daemon.
mai 06 06:09:57 jammy systemd[1]: snapd.service: Consumed 24.749s CPU time.
mai 06 06:10:01 jammy systemd[1]: Starting Snap Daemon...
mai 06 06:10:01 jammy snapd[185708]: AppArmor status: apparmor is enabled and all features are available
mai 06 06:10:01 jammy snapd[185708]: overlord.go:263: Acquiring state lock file
mai 06 06:10:01 jammy snapd[185708]: overlord.go:268: Acquired state lock file
mai 06 06:10:01 jammy snapd[185708]: patch.go:63: Patching system state level 6 to sublevel 1...
mai 06 06:10:01 jammy snapd[185708]: patch.go:63: Patching system state level 6 to sublevel 2...
mai 06 06:10:01 jammy snapd[185708]: patch.go:63: Patching system state level 6 to sublevel 3...
mai 06 06:10:01 jammy snapd[185708]: daemon.go:247: started snapd/2.55.3+22.04ubuntu1 (series 16; classic) ubuntu/22.04 (amd64) linux/5.15.0-27-generic.
mai 06 06:10:01 jammy snapd[185708]: daemon.go:340: adjusting startup timeout by 1m30s (pessimistic estimate of 30s plus 5s per snap)
mai 06 06:10:01 jammy snapd[185708]: backend.go:133: snapd enabled NFS support, additional implicit network permissions granted
mai 06 06:10:06 jammy systemd[1]: Started Snap Daemon.

Here the export lines

/virt 162.38.80.0/21(ro,async,fsid=0,crossmnt,no_subtree_check,anonuid=65534,anongid=65534)
/virt/home  162.38.80.0/21(rw,async,no_subtree_check,root_squash) 

OK. One more question: can you show the output of

ls -l /var/lib/snapd/apparmor/snap-confine

and, if you have a file called nfs-support in there, can you show its contents?

$ cat /var/lib/snapd/apparmor/snap-confine/nfs-support 

  # snapd autogenerated workaround for systems using NFS, for details see:
  # https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1662552
  network inet,
  network inet6,

Nice, so far so good. :slight_smile:

Then, can you please show the contents of /etc/apparmor.d/usr.lib.snapd.snap-confine.real (or /etc/apparmor.d/usr.lib.snapd.snap-confine if that is missing)?

$  file /var/lib/snapd/apparmor/snap-confine/nfs-support && cat /etc/apparmor.d/usr.lib.snapd.snap-confin
e.real
/var/lib/snapd/apparmor/snap-confine/nfs-support: ASCII text
# Author: Jamie Strandboge <jamie@canonical.com>
#include <tunables/global>

/usr/lib/snapd/snap-confine (attach_disconnected) {
    # Include any additional files that snapd chose to generate.
    # - for $HOME on NFS
    # - for $HOME on encrypted media
    #
    # Those are discussed on https://forum.snapcraft.io/t/snapd-vs-upstream-kernel-vs-apparmor
    # and https://forum.snapcraft.io/t/snaps-and-nfs-home/
    #include "/var/lib/snapd/apparmor/snap-confine"

    # We run privileged, so be fanatical about what we include and don't use
    # any abstractions
    /etc/ld.so.cache r,
    /etc/ld.so.preload r,

    # Do not assume that the interpreter is always named like
    # ld-linux-x86_64.so, as on some architectures there can be a version after
    # the .so suffix, eg. ld-linux-aarch64.so.1
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}ld{-*,64}.so* mrix,
    # libc, you are funny
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libc{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libpthread{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libreadline{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}librt{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libgcc_s.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libncursesw{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libresolv{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libselinux.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libpcre{,2}{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libmount.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libblkid.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libuuid.so* mr,
    # normal libs in order
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libapparmor.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcgmanager.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libdl{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih-dbus.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libdbus-1.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libudev.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libseccomp.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcap.so* mr,

    /usr/lib/snapd/snap-confine mr,

    # This rule is needed when executing from a "base: core" devmode snap on 
    # UC18 and newer where the /usr/lib/snapd/snap-confine inside the 
    # "base: core" mount namespace always comes from the snapd snap, and thus
    # we will execute snap-confine via this path, and thus need to be able to
    # read this path when executing. It's also necessary on classic where both
    # the snapd and the core snap are installed at the same time.
    # TODO: remove this rule when we stop supporting executing other snaps from
    # inside devmode snaps, ideally even in the short term we would only include
    # this rule on core only, and specifically uc18 and newer where we need it
    #@VERBATIM_LIBEXECDIR_SNAP_CONFINE@ mr,

    /dev/null rw,
    /dev/full rw,
    /dev/zero rw,
    /dev/random r,
    /dev/urandom r,
    /dev/pts/[0-9]* rw,
    /dev/tty rw,

    # cgroup: devices
    capability sys_admin,
    capability dac_read_search,
    capability dac_override,
    /sys/fs/cgroup/ r,
    /sys/fs/cgroup/devices/ r,
    /sys/fs/cgroup/devices/snap.*/ rw,
    /sys/fs/cgroup/devices/snap.*/cgroup.procs w,
    /sys/fs/cgroup/devices/snap.*/devices.{allow,deny} w,

    # cgroup: freezer
    # Allow creating per-snap cgroup freezers and adding snap command (task)
    # invocations to the freezer. This allows for reliably enumerating all
    # running processes for the snap. In addition, allow enumerating processes
    # in the cgroup to determine if it is occupied.
    /sys/fs/cgroup/freezer/ r,
    /sys/fs/cgroup/freezer/snap.*/ w,
    /sys/fs/cgroup/freezer/snap.*/cgroup.procs rw,
    /sys/fs/cgroup/ r,
    /sys/fs/cgroup/** r,

    # cgroup: reading own cgroup
    @{PROC}/@{pid}/cgroup r,

    # cgroup: manage bpf map for device cgroup
    /sys/fs/bpf/ r,
    /sys/fs/bpf/snap/ rw,
    /sys/fs/bpf/snap/* rw,
    # s-c may need to raise the memlock limit
    capability sys_resource,

    # querying udev
    /etc/udev/udev.conf r,
    /sys/**/uevent r,
    /run/udev/** rw,
    /{,usr/}bin/tr ixr,
    /usr/lib/locale/** r,
    /usr/lib/@{multiarch}/gconv/gconv-modules r,
    /usr/lib/@{multiarch}/gconv/gconv-modules.cache r,

    # priv dropping
    capability setuid,
    capability setgid,

    # changing profile
    @{PROC}/[0-9]*/attr/{,apparmor/}exec w,
    # Reading current profile
    @{PROC}/[0-9]*/attr/{,apparmor/}current r,
    # Reading available filesystems
    @{PROC}/filesystems r,

    # To find where apparmor is mounted
    @{PROC}/[0-9]*/mounts r,
    # To find if apparmor is enabled
    /sys/module/apparmor/parameters/enabled r,

    # Don't allow changing profile to unconfined or profiles that start with
    # '/'. Use 'unsafe' to support snap-exec on armhf and its reliance on
    # the environment for determining the capabilities of the architecture.
    # 'unsafe' is ok here because the kernel will have already cleared the
    # environment as part of launching snap-confine with CAP_SYS_ADMIN. This
    # does leave directories as configured by ld.so.preload as well as
    # LD_PRELOAD to be set to a library which is in a directory configured by
    # ld.so.conf, but access to those locations is mediated by this profile
    # (which requires rules for specific locations).
    change_profile unsafe /** -> [^u/]**,
    change_profile unsafe /** -> u[^n]**,
    change_profile unsafe /** -> un[^c]**,
    change_profile unsafe /** -> unc[^o]**,
    change_profile unsafe /** -> unco[^n]**,
    change_profile unsafe /** -> uncon[^f]**,
    change_profile unsafe /** -> unconf[^i]**,
    change_profile unsafe /** -> unconfi[^n]**,
    change_profile unsafe /** -> unconfin[^e]**,
    change_profile unsafe /** -> unconfine[^d]**,
    change_profile unsafe /** -> unconfined?**,

    # allow changing to a few not caught above
    change_profile unsafe /** -> {u,un,unc,unco,uncon,unconf,unconfi,unconfin,unconfine},

    # LP: #1446794 - when this bug is fixed, change the above to:
    # deny change_profile unsafe /** -> {unconfined,/**},
    # change_profile unsafe /** -> **,

    # reading seccomp filters
    /{tmp/snap.rootfs_*/,}var/lib/snapd/seccomp/bpf/*.bin r,

    # adding a missing bpf mount
    mount fstype=bpf options=(rw) bpf -> /sys/fs/bpf/,

    # LP: #1668659 and parallel instaces of classic snaps
    mount options=(rw rbind) /snap/ -> /snap/,
    mount options=(rw rshared) -> /snap/,
    mount options=(rw rbind) /var/lib/snapd/snap/ -> /var/lib/snapd/snap/,
    mount options=(rw rshared) -> /var/lib/snapd/snap/,

    # boostrapping the mount namespace
    mount options=(rw rshared) -> /,
    mount options=(rw bind) /tmp/snap.rootfs_*/ -> /tmp/snap.rootfs_*/,
    mount options=(rw unbindable) -> /tmp/snap.rootfs_*/,
    # the next line is for classic system
    mount options=(rw rbind) /snap/*/*/ -> /tmp/snap.rootfs_*/,
    # the next line is for core system
    mount options=(rw rbind) / -> /tmp/snap.rootfs_*/,
    # all of the constructed rootfs is a rslave
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/,
    # bidirectional mounts (for both classic and core)
    # NOTE: this doesn't capture the MERGED_USR configuration option so that
    # when a distro with merged /usr and / that uses apparmor shows up it
    # should be handled here.
    /{,run/}media/ w,
    mount options=(rw rbind) /{,run/}media/ -> /tmp/snap.rootfs_*/{,run/}media/,
    /run/netns/ w,
    mount options=(rw rbind) /run/netns/ -> /tmp/snap.rootfs_*/run/netns/,
    # unidirectional mounts (only for classic system)
    mount options=(rw rbind) /dev/ -> /tmp/snap.rootfs_*/dev/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/dev/,

    mount options=(rw rbind) /etc/ -> /tmp/snap.rootfs_*/etc/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/etc/,

    mount options=(rw rbind) /home/ -> /tmp/snap.rootfs_*/home/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/home/,

    mount options=(rw rbind) /root/ -> /tmp/snap.rootfs_*/root/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/root/,

    mount options=(rw rbind) /proc/ -> /tmp/snap.rootfs_*/proc/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/proc/,

    mount options=(rw rbind) /sys/ -> /tmp/snap.rootfs_*/sys/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/sys/,

    mount options=(rw rbind) /tmp/ -> /tmp/snap.rootfs_*/tmp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/tmp/,

    mount options=(rw rbind) /var/lib/dhcp/ -> /tmp/snap.rootfs_*/var/lib/dhcp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/dhcp/,

    mount options=(rw rbind) /var/lib/snapd/ -> /tmp/snap.rootfs_*/var/lib/snapd/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/snapd/,

    mount options=(rw rbind) /var/snap/ -> /tmp/snap.rootfs_*/var/snap/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/snap/,

    mount options=(rw rbind) /var/tmp/ -> /tmp/snap.rootfs_*/var/tmp/,
    # /var/volatile is the default volatile location on Yocto/Poky, typically used with read-only rootfs setups
    mount options=(rw rbind) /var/volatile/tmp/ -> /tmp/snap.rootfs_*/var/tmp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/tmp/,

    mount options=(rw rbind) /run/ -> /tmp/snap.rootfs_*/run/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/run/,

    mount options=(rw rbind) /var/lib/extrausers/ -> /tmp/snap.rootfs_*/var/lib/extrausers/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/extrausers/,

    mount options=(rw rbind) {,/usr}/lib{,32,64,x32}/modules/ -> /tmp/snap.rootfs_*{,/usr}/lib/modules/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*{,/usr}/lib/modules/,

    mount options=(rw rbind) {,/usr}/lib{,32,64,x32}/firmware/ -> /tmp/snap.rootfs_*{,/usr}/lib/firmware/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*{,/usr}/lib/firmware/,

    mount options=(rw rbind) /var/log/ -> /tmp/snap.rootfs_*/var/log/,
    # /var/volatile is the default volatile location on Yocto/Poky, typically used with read-only rootfs setups
    mount options=(rw rbind) /var/volatile/log/ -> /tmp/snap.rootfs_*/var/log/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/log/,

    mount options=(rw rbind) /usr/src/ -> /tmp/snap.rootfs_*/usr/src/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/usr/src/,

    mount options=(rw rbind) /mnt/ -> /tmp/snap.rootfs_*/mnt/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/mnt/,

    # allow making host snap-exec available inside base snaps
    mount options=(rw bind) /usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/usr/lib/snapd/,

    # allow making re-execed host snap-exec available inside base snaps
    mount options=(ro bind) /snap/core/*/usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,
    # allow making snapd snap tools available inside base snaps
    mount options=(ro bind) /snap/snapd/*/usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,

    mount options=(rw bind) /usr/bin/snapctl -> /tmp/snap.rootfs_*/usr/bin/snapctl,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/usr/bin/snapctl,

    # /etc/alternatives (classic and normal mode)
    mount options=(rw bind) /snap/*/*/etc/alternatives/ -> /tmp/snap.rootfs_*/etc/alternatives/,
    mount options=(rw bind) /snap/*/*/etc/ssl/ -> /tmp/snap.rootfs_*/etc/ssl/,
    mount options=(rw bind) /snap/*/*/etc/nsswitch.conf -> /tmp/snap.rootfs_*/etc/nsswitch.conf,
    mount options=(rw bind) /snap/*/*/etc/apparmor/ -> /tmp/snap.rootfs_*/etc/apparmor/,
    mount options=(rw bind) /snap/*/*/etc/apparmor.d/ -> /tmp/snap.rootfs_*/etc/apparmor.d/,

    # /etc/alternatives (core/legacy mode)
    mount options=(rw bind) /etc/alternatives/ -> /tmp/snap.rootfs_*/etc/alternatives/,

    # making all those directories slave shared.
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/alternatives/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/ssl/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/nsswitch.conf,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/apparmor/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/apparmor.d/,

    # the /snap directory
    mount options=(rw rbind) /snap/ -> /tmp/snap.rootfs_*/snap/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/snap/,
    # pivot_root preparation and execution
    mount options=(rw bind) /tmp/snap.rootfs_*/var/lib/snapd/hostfs/ -> /tmp/snap.rootfs_*/var/lib/snapd/hostfs/,
    mount options=(rw private) -> /tmp/snap.rootfs_*/var/lib/snapd/hostfs/,

    # pivot_root mediation in AppArmor is not complete. See LP: #1791711.
    # However, we can mediate the new_root and put_old to be what we expect,
    # and then deny directory creation within old_root to prevent trivial
    # pivoting into a whitelisted path.
    pivot_root oldroot=/tmp/snap.rootfs_*/var/lib/snapd/hostfs/ /tmp/snap.rootfs_*/,
    # Explicitly deny creating the old_root directory in case it is
    # inadvertently added somewhere else. While this doesn't resolve
    # LP: #1791711, it provides some hardening.
    audit deny /tmp/snap.rootfs_*/{var/,var/lib/,var/lib/snapd/,var/lib/snapd/hostfs/} w,

    # cleanup
    umount /var/lib/snapd/hostfs/tmp/snap.rootfs_*/,
    umount /var/lib/snapd/hostfs/sys/,
    umount /var/lib/snapd/hostfs/dev/,
    umount /var/lib/snapd/hostfs/proc/,
    mount options=(rw rslave) -> /var/lib/snapd/hostfs/,

    # Hide /writable from view of snaps.
    mount options=(rprivate) -> /{,var/lib/snapd/hostfs/}writable/,
    umount /{,var/lib/snapd/hostfs/}writable/,

    # set up user mount namespace
    mount options=(rslave) -> /,

    # set up mount namespace for parallel instances of classic snaps
    mount options=(rw rbind) /snap/{,*/} -> /snap/{,*/},
    mount options=(rslave) -> /snap/,
    mount options=(rslave) -> /var/snap/,
    mount options=(rw rbind) /var/snap/{,*/} -> /var/snap/{,*/},
    mount options=(rw rshared) -> /var/snap/,

    # Allow reading the os-release file (possibly a symlink to /usr/lib).
    /{etc/,usr/lib/}os-release r,

    # Allow creating /var/lib/snapd/hostfs, if missing
    /var/lib/snapd/hostfs/ rw,

    # set up snap-specific private /tmp dir
    capability chown,
    /tmp/ rw,
    /tmp/snap.*/ rw,
    /tmp/snap.*/tmp/ rw,
    mount options=(rw private) ->  /tmp/,
    mount options=(rw bind) /tmp/snap.*/tmp/ -> /tmp/,
    mount fstype=devpts options=(rw) devpts -> /dev/pts/,
    mount options=(rw bind) /dev/pts/ptmx -> /dev/ptmx,     # for bind mounting
    mount options=(rw bind) /dev/pts/ptmx -> /dev/pts/ptmx, # for bind mounting under LXD
    # Workaround for LP: #1584456 on older kernels that mistakenly think
    # /dev/pts/ptmx needs a trailing '/'
    mount options=(rw bind) /dev/pts/ptmx/ -> /dev/ptmx/,
    mount options=(rw bind) /dev/pts/ptmx/ -> /dev/pts/ptmx/,

    # for running snaps on classic
    /snap/ r,
    /snap/** r,
    /snap/ r,
    /snap/** r,

    # NOTE: at this stage the /snap directory is stable as we have called
    # pivot_root already.

    # nvidia handling, glob needs /usr/** and the launcher must be
    # able to bind mount the nvidia dir
    /sys/module/nvidia/version r,
    /sys/**/drivers/nvidia{,_*}/* r,
    /sys/**/nvidia*/uevent r,
    /sys/module/nvidia{,_*}/* r,
    /dev/nvidia[0-9]* r,
    /dev/nvidiactl r,
    /dev/nvidia-uvm r,
    /usr/** r,
    mount options=(rw bind) /usr/lib{,32}/nvidia-*/ -> /{tmp/snap.rootfs_*/,}var/lib/snapd/lib/gl{,32}/,
    mount options=(rw bind) /usr/lib{,32}/nvidia-*/ -> /{tmp/snap.rootfs_*/,}var/lib/snapd/lib/gl{,32}/,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/,

    # Vulkan support
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/,

    # GLVND EGL vendor
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/,

    # create gl dirs as needed
    /tmp/snap.rootfs_*/ r,
    /tmp/snap.rootfs_*/var/ r,
    /tmp/snap.rootfs_*/var/lib/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/** rw,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/** rw,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/** rw,

    # for chroot on steroids, we use pivot_root as a better chroot that makes
    # apparmor rules behave the same on classic and outside of classic.

    # for creating the user data directories: ~/snap, ~/snap/<name> and
    # ~/snap/<name>/<version>
    / r,
    @{HOMEDIRS}/ r,
    # These should both have 'owner' match but due to LP: #1466234, we can't
    # yet
    @{HOME}/ r,
    @{HOME}/snap/{,*/,*/*/} rw,

    # experimental
    @{HOME}/.snap/                rw,
    @{HOME}/.snap/data/{,*/,*/*/} rw,
    @{HOME}/Snap/{,*/,*/*/}       rw,

    # Special case for *classic* snaps that are used by users with existing dirs
    # in /var/lib/. Like jenkins, postgresql, mysql, puppet, ...
    # (see https://forum.snapcraft.io/t/9717)
    # TODO: this can be removed once we support home-dirs outside of /home
    #       better
    /var/ r,
    /var/lib/ r,
    # These should both have 'owner' match but due to LP: #1466234, we can't
    # yet
    /var/lib/*/ r,
    /var/lib/*/snap/{,*/,*/*/} rw,

    # for creating the user shared memory directories
    /{dev,run}/{,shm/} r,
    # This should both have 'owner' match but due to LP: #1466234, we can't yet
    /{dev,run}/shm/{,*/,*/*/} rw,

    # for creating the user XDG_RUNTIME_DIR: /run/user, /run/user/UID and
    # /run/user/UID/<name>
    /run/user/{,[0-9]*/,[0-9]*/*/} rw,

    # Workaround https://launchpad.net/bugs/359338 until upstream handles
    # stacked filesystems generally.
    # encrypted ~/.Private and old-style encrypted $HOME
    @{HOME}/.Private/ r,
    @{HOME}/.Private/** mrwlk,
    # new-style encrypted $HOME
    @{HOMEDIRS}/.ecryptfs/*/.Private/ r,
    @{HOMEDIRS}/.ecryptfs/*/.Private/** mrwlk,

    # Allow snap-confine to move to the void, creating it if necessary.
    /var/lib/snapd/void/ rw,

    # Allow snap-confine to read snap contexts
    /var/lib/snapd/context/snap.* r,

    # Allow snap-confine to unmount stale mount namespaces.
    umount /run/snapd/ns/*.mnt,
    /run/snapd/ns/snap.*.fstab w,
    # Allow snap-confine to read and write mount namespace information files.
    /run/snapd/ns/snap.*.info rw,
    # Required to correctly unmount bound mount namespace.
    # See LP: #1735459 for details.
    umount /,

    # support for locking
    /run/snapd/lock/ rw,
    /run/snapd/lock/*.lock rwk,

    # support for the mount namespace sharing
    capability sys_ptrace,
    # allow snap-confine to read /proc/1/ns/mnt
    ptrace read peer=unconfined,
    # https://forum.snapcraft.io/t/custom-kernel-error-on-readlinkat-in-mount-namespace/6097/21
    ptrace trace peer=unconfined,

    mount options=(rw rbind) /run/snapd/ns/ -> /run/snapd/ns/,
    mount options=(private) -> /run/snapd/ns/,
    / rw,
    /run/ rw,
    /run/snapd/ rw,
    /run/snapd/ns/ rw,
    /run/snapd/ns/*.lock rwk,
    /run/snapd/ns/*.mnt rw,
    ptrace (read, readby, tracedby) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
    @{PROC}/*/mountinfo r,
    capability sys_chroot,
    capability sys_admin,
    signal (send, receive) set=(abrt) peer=/usr/lib/snapd/snap-confine,
    signal (send) set=(int) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
    signal (send, receive) set=(int, alrm, exists) peer=/usr/lib/snapd/snap-confine,
    signal (receive) set=(exists) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,

    # workaround for linux 4.13/upstream, see
    # https://forum.snapcraft.io/t/snapd-2-27-6-2-in-debian-sid-blocked-on-apparmor-in-kernel-4-13-0-1/2813/3
    ptrace (trace, tracedby) peer=/usr/lib/snapd/snap-confine,

    # Allow reading snap cookies.
    /var/lib/snapd/cookie/snap.* r,

    # For aa_change_hat() to go into ^mount-namespace-capture-helper
    @{PROC}/[0-9]*/attr/{,apparmor/}current w,

    # As a special exception allow snap-confine to write to anything in /var/lib.
    # This code should be changed to allow delegation so that snap-confine can
    # inherit any file descriptor and pass it to the invoked application but
    # this is not possible in apparmor yet.
    # See https://bugs.launchpad.net/snapd/+bug/1815869
    /var/lib/** rw,

    ^mount-namespace-capture-helper (attach_disconnected) {
        # We run privileged, so be fanatical about what we include and don't use
        # any abstractions
        /etc/ld.so.cache r,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}ld{-*,64}.so* mrix,
        # libc, you are funny
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libc{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libpthread{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libreadline{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}librt{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libgcc_s.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libncursesw{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libresolv{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libselinux.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libpcre.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libmount.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libblkid.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libuuid.so* mr,
        # normal libs in order
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libapparmor.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcgmanager.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libdl{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih-dbus.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libdbus-1.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libudev.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libseccomp.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcap.so* mr,

        /usr/lib/snapd/snap-confine mr,

        /dev/null rw,
        /dev/full rw,
        /dev/zero rw,
        /dev/random r,
        /dev/urandom r,

        capability sys_ptrace,
        capability sys_admin,
        # This allows us to read and bind mount the namespace file
        / r,
        @{PROC}/ r,
        @{PROC}/*/ r,
        @{PROC}/*/ns/ r,
        @{PROC}/*/ns/mnt r,
        /run/ r,
        /run/snapd/ r,
        /run/snapd/ns/ r,
        /run/snapd/ns/*.mnt rw,
        # NOTE: the source name is / even though we map /proc/123/ns/mnt
        mount options=(rw bind) / -> /run/snapd/ns/*.mnt,
        # This is the SIGALRM that we send and receive if a timeout expires
        signal (send, receive) set=(alrm) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
        # Those two rules are exactly the same but we don't know if the parent process is still alive
        # and hence has the appropriate label or is already dead and hence has no label.
        signal (send) set=(exists) peer=/usr/lib/snapd/snap-confine,
        signal (send) set=(exists) peer=unconfined,
        # This is so that we can abort
        signal (send, receive) set=(abrt) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
        #  This is the signal we get if snap-confine dies (we subscribe to it with prctl)
        signal (receive) set=(int) peer=/usr/lib/snapd/snap-confine,
        # This allows snap-confine to be killed from the outside.
        signal (receive) peer=unconfined,
        # This allows snap-confine to wait for us
        ptrace (read, trace, tracedby) peer=/usr/lib/snapd/snap-confine,
    }

    # Allow snap-confine to be killed
    signal (receive) peer=unconfined,

    # Allow switching to snap-update-ns with a per-snap profile.
    change_profile -> snap-update-ns.*,

    # Allow executing snap-update-ns when...

    # ...snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the distribution package. This is also the location used when using
    # the core/base snap on all-snap systems. The variants here represent
    # various locations of libexecdir across distributions.
    /usr/lib{,exec,64}/snapd/snap-update-ns r,

    # ...snap-confine is not, conceptually, re-executing and uses
    # snap-update-ns from the distribution package but we are already inside
    # the constructed mount namespace so we must traverse "hostfs". The
    # variants here represent various locations of libexecdir across
    # distributions.
    /var/lib/snapd/hostfs/usr/lib{,exec,64}/snapd/snap-update-ns r,

    # ..snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the core or snapd snaps. Note that the location of the actual snap
    # varies from distribution to distribution. The variants here represent
    # different locations of snap mount directory across distributions.
    /{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-update-ns r,

    # ...snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the core snap or snapd snap, but we are already inside the
    # constructed mount namespace. Here the apparmor kernel module
    # re-constructs the path to snap-update-ns using the "hostfs" mount entry
    # rather than the more "natural" /snap mount entry but we have no control
    # over that.  This is reported as (LP: #1716339). The variants here
    # represent different locations of snap mount directory across
    # distributions.
    /var/lib/snapd/hostfs/{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-update-ns r,

    # Allow executing snap-discard-ns, just like the set for snap-update-ns
    # above but with the key difference that snap-discard-ns does not
    # have a dedicated profile so we need to inherit snap-confine's profile.

    /usr/lib{,exec,64}/snapd/snap-discard-ns rix,
    /var/lib/snapd/hostfs/usr/lib{,exec,64}/snapd/snap-discard-ns rix,
    /{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-discard-ns rix,
    /var/lib/snapd/hostfs/{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-discard-ns rix,

    # Allow mounting /var/lib/jenkins from the host into the snap.
    mount options=(rw rbind) /var/lib/jenkins/ -> /tmp/snap.rootfs_*/var/lib/jenkins/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/jenkins/,

    # Suppress noisy file_inherit denials (LP: #1850552) until LP: #1849753 is
    # fixed.
    deny /dev/shm/.org.chromium.Chromium.* rw,

    # While snap-confine itself doesn't require unix rules and therefore all
    # unix rules are implicitly denied, adding an explicit deny for unix to
    # silence noisy denials breaks nested lxd. Until the cause is determined,
    # do not use an explicit deny for unix. (LP: #1855355)
    #deny unix,

    # Explicitly deny these accesses which show up on Arch to silence the
    # denials for this unneeded access.
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_files-[0-9]*.so* mr,
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_mymachines.[0-9]*.so* mr,
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_systemd.[0-9]*.so* mr,
    deny /etc/nsswitch.conf r,
    deny /etc/passwd r,
}
file /var/lib/snapd/apparmor/snap-confine/nfs-support && apparmor_parser  -p /etc/apparmor.d/usr.lib.snapd.snap-confine.real
/var/lib/snapd/apparmor/snap-confine/nfs-support: ASCII text
# Author: Jamie Strandboge <jamie@canonical.com>
 

##included <tunables/global>
# ------------------------------------------------------------------
#
#    Copyright (C) 2006-2009 Novell/SUSE
#    Copyright (C) 2010-2014 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# All the tunables definitions that should be available to every profile
# should be included here

 

##included <tunables/home>
# ------------------------------------------------------------------
#
#    Copyright (C) 2006-2009 Novell/SUSE
#    Copyright (C) 2010 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# @{HOME} is a space-separated list of all user home directories. While
# it doesn't refer to a specific home directory (AppArmor doesn't
# enforce discretionary access controls) it can be used as if it did
# refer to a specific home directory
@{HOME}=@{HOMEDIRS}/*/ /root/


# @{HOMEDIRS} is a space-separated list of where user home directories
# are stored, for programs that must enumerate all home directories on a
# system.
@{HOMEDIRS}=/home/*/


# Also, include files in tunables/home.d for site-specific adjustments to
# @{HOMEDIRS}.
 

##included <tunables/home.d>
# This file is auto-generated. It is recommended you update it using:
# $ sudo dpkg-reconfigure apparmor
#
# The following is a space-separated list of where additional user home
# directories are stored, each must have a trailing '/'. Directories added
# here are appended to @{HOMEDIRS}.  See tunables/home for details.
@{HOMEDIRS}+=/home/*/

# ------------------------------------------------------------------
#
#    Copyright (C) 2010 Canonical Ltd.
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# The following is a space-separated list of where additional user home
# directories are stored, each must have a trailing '/'. Directories added
# here are appended to @{HOMEDIRS}.  See tunables/home for details. Eg:
#@{HOMEDIRS}+=/srv/nfs/home/ /mnt/home/


 

##included <tunables/multiarch>
# ------------------------------------------------------------------
#
#    Copyright (C) 2010 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# @{multiarch} is the set of patterns matching multi-arch library
# install prefixes.
@{multiarch}=*-linux-gnu*


# Also, include files in tunables/multiarch.d for site and packaging
# specific adjustments to @{multiarch}.
 

##included <tunables/multiarch.d>
# ------------------------------------------------------------------
#
#    Copyright (C) 2011 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# The following is a space-separated list of where additional multipath
# prefixes are stored, each should not have a trailing '/'. Directories
# added here are appended to @{multiarch}. See tunables/mutliarch for details. Eg:
#@{multiarch}+=*-freebsd* s390-hurd-zomg


 

##included <tunables/proc>
# ------------------------------------------------------------------
#
#    Copyright (C) 2006 Novell/SUSE
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# @{PROC} is the location where procfs is mounted.
@{PROC}=/proc/


 

##included <tunables/alias>
# ------------------------------------------------------------------
#
#    Copyright (C) 2010 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# Alias rules can be used to rewrite paths and are done after variable
# resolution. For example, if '/usr' is on removable media:
# alias /usr/ -> /mnt/usr/,
#
# Or if mysql databases are stored in /home:
# alias /var/lib/mysql/ -> /home/mysql/,

 

##included <tunables/kernelvars>
#    Copyright (C) 2012 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# This file should contain declarations to kernel vars or variables
# that will become kernel vars at some point

# until kernel vars are implemented
# and until the parser supports nested groupings like
#   @{pid}=[1-9]{[0-9]{[0-9]{[0-9]{[0-9]{[0-9],},},},},}
# use
@{pid}={[1-9],[1-9][0-9],[1-9][0-9][0-9],[1-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9],[1-4][0-9][0-9][0-9][0-9][0-9][0-9]}


#same pattern as @{pid} for now
@{tid}=@{pid}


#A pattern for pids that can appear
@{pids}=@{pid}


# Placeholder for user id until kernel var is implemented to match
# current user of the confined application.
# Values are 0...4,294,967,295 (32-bit unsigned, 10 digits).
@{uid}={[0-9],[1-9][0-9],[1-9][0-9][0-9],[1-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],[1-4][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}


#same pattern as @{uid} for now
@{uids}=@{uid}


# until kernel var is implemented
@{sys}=/sys/


 

##included <tunables/xdg-user-dirs>
# ------------------------------------------------------------------
#
#    Copyright (C) 2014 Canonical Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# Define the common set of XDG user directories (usually defined in
# /etc/xdg/user-dirs.defaults)
@{XDG_DESKTOP_DIR}="Desktop"

@{XDG_DOWNLOAD_DIR}="Downloads"

@{XDG_TEMPLATES_DIR}="Templates"

@{XDG_PUBLICSHARE_DIR}="Public"

@{XDG_DOCUMENTS_DIR}="Documents"

@{XDG_MUSIC_DIR}="Music"

@{XDG_PICTURES_DIR}="Pictures"

@{XDG_VIDEOS_DIR}="Videos"


# Also, include files in tunables/xdg-user-dirs.d for site-specific adjustments
# to the various XDG directories
 

##included <tunables/xdg-user-dirs.d>
# ------------------------------------------------------------------
#
#    Copyright (C) 2014 Canonical Ltd.
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# The following may be used to add additional entries such as for
# translations. See tunables/xdg-user-dirs for details. Eg:
#@{XDG_MUSIC_DIR}+="Musique"

#@{XDG_DESKTOP_DIR}+=""
#@{XDG_DOWNLOAD_DIR}+=""
#@{XDG_TEMPLATES_DIR}+=""
#@{XDG_PUBLICSHARE_DIR}+=""
#@{XDG_DOCUMENTS_DIR}+=""
#@{XDG_MUSIC_DIR}+=""
#@{XDG_PICTURES_DIR}+=""
#@{XDG_VIDEOS_DIR}+=""


 

##included <tunables/share>
@{flatpak_exports_root} = {flatpak/exports,flatpak/{app,runtime}/*/*/*/*/export}


# System-wide directories with behaviour analogous to /usr/share
# in patterns like the freedesktop.org basedir spec. These are
# owned by root or a system user, appear in XDG_DATA_DIRS, and
# are the parent directory for `applications`, `themes`,
# `dbus-1/services`, etc.
@{system_share_dirs} = /{usr,usr/local,var/lib/@{flatpak_exports_root}}/share


# Per-user/personal directories with behaviour analogous to
# ~/.local/share in patterns like the freedesktop.org basedir spec.
# These are owned by the user running an application, appear in
# XDG_DATA_DIRS or XDG_DATA_HOME, and are the parent directory
# for the same subdirectories as @{system_share_dirs}
@{user_share_dirs} = @{HOME}/.local{,/share/@{flatpak_exports_root}}/share


 

##included <tunables/etc>
# ------------------------------------------------------------------
#
#    Copyright (C) 2020 Christian Boltz
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

# @{etc_ro} contains a space-separated list of the system configuration directories.
# Traditionally this means /etc/, but when using a read-only / filesystem and/or
# with the goal of having only user-modified config files in /etc/, directories
# like /usr/etc/ get introduced for storing the default config.

# @{etc_ro} contains read-only directories with configuration files.
# Do not use @{etc_ro} in rules that allow write access.
@{etc_ro}=/etc/ /usr/etc/


# @{etc_rw} contains directories where writing to configuration files is allowed.
@{etc_rw}=/etc/


# Also, include files in tunables/etc.d/ for site-specific adjustments to
# @{etc_ro} and @{etc_rw}.
 

##included <tunables/etc.d>


 

##included <tunables/run>
@{run}=/run/ /var/run/




/usr/lib/snapd/snap-confine (attach_disconnected) {
    # Include any additional files that snapd chose to generate.
    # - for $HOME on NFS
    # - for $HOME on encrypted media
    #
    # Those are discussed on https://forum.snapcraft.io/t/snapd-vs-upstream-kernel-vs-apparmor
    # and https://forum.snapcraft.io/t/snaps-and-nfs-home/
     

##included "/var/lib/snapd/apparmor/snap-confine"

  # snapd autogenerated workaround for systems using NFS, for details see:
  # https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1662552
  network inet,
  network inet6,

capability bpf,


    # We run privileged, so be fanatical about what we include and don't use
    # any abstractions
    /etc/ld.so.cache r,
    /etc/ld.so.preload r,

    # Do not assume that the interpreter is always named like
    # ld-linux-x86_64.so, as on some architectures there can be a version after
    # the .so suffix, eg. ld-linux-aarch64.so.1
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}ld{-*,64}.so* mrix,
    # libc, you are funny
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libc{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libpthread{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libreadline{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}librt{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libgcc_s.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libncursesw{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libresolv{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libselinux.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libpcre{,2}{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libmount.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libblkid.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libuuid.so* mr,
    # normal libs in order
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libapparmor.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcgmanager.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libdl{,-[0-9]*}.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih-dbus.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libdbus-1.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libudev.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libseccomp.so* mr,
    /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcap.so* mr,

    /usr/lib/snapd/snap-confine mr,

    # This rule is needed when executing from a "base: core" devmode snap on 
    # UC18 and newer where the /usr/lib/snapd/snap-confine inside the 
    # "base: core" mount namespace always comes from the snapd snap, and thus
    # we will execute snap-confine via this path, and thus need to be able to
    # read this path when executing. It's also necessary on classic where both
    # the snapd and the core snap are installed at the same time.
    # TODO: remove this rule when we stop supporting executing other snaps from
    # inside devmode snaps, ideally even in the short term we would only include
    # this rule on core only, and specifically uc18 and newer where we need it
    #@VERBATIM_LIBEXECDIR_SNAP_CONFINE@ mr,

    /dev/null rw,
    /dev/full rw,
    /dev/zero rw,
    /dev/random r,
    /dev/urandom r,
    /dev/pts/[0-9]* rw,
    /dev/tty rw,

    # cgroup: devices
    capability sys_admin,
    capability dac_read_search,
    capability dac_override,
    /sys/fs/cgroup/ r,
    /sys/fs/cgroup/devices/ r,
    /sys/fs/cgroup/devices/snap.*/ rw,
    /sys/fs/cgroup/devices/snap.*/cgroup.procs w,
    /sys/fs/cgroup/devices/snap.*/devices.{allow,deny} w,

    # cgroup: freezer
    # Allow creating per-snap cgroup freezers and adding snap command (task)
    # invocations to the freezer. This allows for reliably enumerating all
    # running processes for the snap. In addition, allow enumerating processes
    # in the cgroup to determine if it is occupied.
    /sys/fs/cgroup/freezer/ r,
    /sys/fs/cgroup/freezer/snap.*/ w,
    /sys/fs/cgroup/freezer/snap.*/cgroup.procs rw,
    /sys/fs/cgroup/ r,
    /sys/fs/cgroup/** r,

    # cgroup: reading own cgroup
    @{PROC}/@{pid}/cgroup r,

    # cgroup: manage bpf map for device cgroup
    /sys/fs/bpf/ r,
    /sys/fs/bpf/snap/ rw,
    /sys/fs/bpf/snap/* rw,
    # s-c may need to raise the memlock limit
    capability sys_resource,

    # querying udev
    /etc/udev/udev.conf r,
    /sys/**/uevent r,
    /run/udev/** rw,
    /{,usr/}bin/tr ixr,
    /usr/lib/locale/** r,
    /usr/lib/@{multiarch}/gconv/gconv-modules r,
    /usr/lib/@{multiarch}/gconv/gconv-modules.cache r,

    # priv dropping
    capability setuid,
    capability setgid,

    # changing profile
    @{PROC}/[0-9]*/attr/{,apparmor/}exec w,
    # Reading current profile
    @{PROC}/[0-9]*/attr/{,apparmor/}current r,
    # Reading available filesystems
    @{PROC}/filesystems r,

    # To find where apparmor is mounted
    @{PROC}/[0-9]*/mounts r,
    # To find if apparmor is enabled
    /sys/module/apparmor/parameters/enabled r,

    # Don't allow changing profile to unconfined or profiles that start with
    # '/'. Use 'unsafe' to support snap-exec on armhf and its reliance on
    # the environment for determining the capabilities of the architecture.
    # 'unsafe' is ok here because the kernel will have already cleared the
    # environment as part of launching snap-confine with CAP_SYS_ADMIN. This
    # does leave directories as configured by ld.so.preload as well as
    # LD_PRELOAD to be set to a library which is in a directory configured by
    # ld.so.conf, but access to those locations is mediated by this profile
    # (which requires rules for specific locations).
    change_profile unsafe /** -> [^u/]**,
    change_profile unsafe /** -> u[^n]**,
    change_profile unsafe /** -> un[^c]**,
    change_profile unsafe /** -> unc[^o]**,
    change_profile unsafe /** -> unco[^n]**,
    change_profile unsafe /** -> uncon[^f]**,
    change_profile unsafe /** -> unconf[^i]**,
    change_profile unsafe /** -> unconfi[^n]**,
    change_profile unsafe /** -> unconfin[^e]**,
    change_profile unsafe /** -> unconfine[^d]**,
    change_profile unsafe /** -> unconfined?**,

    # allow changing to a few not caught above
    change_profile unsafe /** -> {u,un,unc,unco,uncon,unconf,unconfi,unconfin,unconfine},

    # LP: #1446794 - when this bug is fixed, change the above to:
    # deny change_profile unsafe /** -> {unconfined,/**},
    # change_profile unsafe /** -> **,

    # reading seccomp filters
    /{tmp/snap.rootfs_*/,}var/lib/snapd/seccomp/bpf/*.bin r,

    # adding a missing bpf mount
    mount fstype=bpf options=(rw) bpf -> /sys/fs/bpf/,

    # LP: #1668659 and parallel instaces of classic snaps
    mount options=(rw rbind) /snap/ -> /snap/,
    mount options=(rw rshared) -> /snap/,
    mount options=(rw rbind) /var/lib/snapd/snap/ -> /var/lib/snapd/snap/,
    mount options=(rw rshared) -> /var/lib/snapd/snap/,

    # boostrapping the mount namespace
    mount options=(rw rshared) -> /,
    mount options=(rw bind) /tmp/snap.rootfs_*/ -> /tmp/snap.rootfs_*/,
    mount options=(rw unbindable) -> /tmp/snap.rootfs_*/,
    # the next line is for classic system
    mount options=(rw rbind) /snap/*/*/ -> /tmp/snap.rootfs_*/,
    # the next line is for core system
    mount options=(rw rbind) / -> /tmp/snap.rootfs_*/,
    # all of the constructed rootfs is a rslave
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/,
    # bidirectional mounts (for both classic and core)
    # NOTE: this doesn't capture the MERGED_USR configuration option so that
    # when a distro with merged /usr and / that uses apparmor shows up it
    # should be handled here.
    /{,run/}media/ w,
    mount options=(rw rbind) /{,run/}media/ -> /tmp/snap.rootfs_*/{,run/}media/,
    /run/netns/ w,
    mount options=(rw rbind) /run/netns/ -> /tmp/snap.rootfs_*/run/netns/,
    # unidirectional mounts (only for classic system)
    mount options=(rw rbind) /dev/ -> /tmp/snap.rootfs_*/dev/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/dev/,

    mount options=(rw rbind) /etc/ -> /tmp/snap.rootfs_*/etc/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/etc/,

    mount options=(rw rbind) /home/ -> /tmp/snap.rootfs_*/home/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/home/,

    mount options=(rw rbind) /root/ -> /tmp/snap.rootfs_*/root/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/root/,

    mount options=(rw rbind) /proc/ -> /tmp/snap.rootfs_*/proc/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/proc/,

    mount options=(rw rbind) /sys/ -> /tmp/snap.rootfs_*/sys/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/sys/,

    mount options=(rw rbind) /tmp/ -> /tmp/snap.rootfs_*/tmp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/tmp/,

    mount options=(rw rbind) /var/lib/dhcp/ -> /tmp/snap.rootfs_*/var/lib/dhcp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/dhcp/,

    mount options=(rw rbind) /var/lib/snapd/ -> /tmp/snap.rootfs_*/var/lib/snapd/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/snapd/,

    mount options=(rw rbind) /var/snap/ -> /tmp/snap.rootfs_*/var/snap/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/snap/,

    mount options=(rw rbind) /var/tmp/ -> /tmp/snap.rootfs_*/var/tmp/,
    # /var/volatile is the default volatile location on Yocto/Poky, typically used with read-only rootfs setups
    mount options=(rw rbind) /var/volatile/tmp/ -> /tmp/snap.rootfs_*/var/tmp/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/tmp/,

    mount options=(rw rbind) /run/ -> /tmp/snap.rootfs_*/run/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/run/,

    mount options=(rw rbind) /var/lib/extrausers/ -> /tmp/snap.rootfs_*/var/lib/extrausers/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/extrausers/,

    mount options=(rw rbind) {,/usr}/lib{,32,64,x32}/modules/ -> /tmp/snap.rootfs_*{,/usr}/lib/modules/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*{,/usr}/lib/modules/,

    mount options=(rw rbind) {,/usr}/lib{,32,64,x32}/firmware/ -> /tmp/snap.rootfs_*{,/usr}/lib/firmware/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*{,/usr}/lib/firmware/,

    mount options=(rw rbind) /var/log/ -> /tmp/snap.rootfs_*/var/log/,
    # /var/volatile is the default volatile location on Yocto/Poky, typically used with read-only rootfs setups
    mount options=(rw rbind) /var/volatile/log/ -> /tmp/snap.rootfs_*/var/log/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/log/,

    mount options=(rw rbind) /usr/src/ -> /tmp/snap.rootfs_*/usr/src/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/usr/src/,

    mount options=(rw rbind) /mnt/ -> /tmp/snap.rootfs_*/mnt/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/mnt/,

    # allow making host snap-exec available inside base snaps
    mount options=(rw bind) /usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/usr/lib/snapd/,

    # allow making re-execed host snap-exec available inside base snaps
    mount options=(ro bind) /snap/core/*/usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,
    # allow making snapd snap tools available inside base snaps
    mount options=(ro bind) /snap/snapd/*/usr/lib/snapd/ -> /tmp/snap.rootfs_*/usr/lib/snapd/,

    mount options=(rw bind) /usr/bin/snapctl -> /tmp/snap.rootfs_*/usr/bin/snapctl,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/usr/bin/snapctl,

    # /etc/alternatives (classic and normal mode)
    mount options=(rw bind) /snap/*/*/etc/alternatives/ -> /tmp/snap.rootfs_*/etc/alternatives/,
    mount options=(rw bind) /snap/*/*/etc/ssl/ -> /tmp/snap.rootfs_*/etc/ssl/,
    mount options=(rw bind) /snap/*/*/etc/nsswitch.conf -> /tmp/snap.rootfs_*/etc/nsswitch.conf,
    mount options=(rw bind) /snap/*/*/etc/apparmor/ -> /tmp/snap.rootfs_*/etc/apparmor/,
    mount options=(rw bind) /snap/*/*/etc/apparmor.d/ -> /tmp/snap.rootfs_*/etc/apparmor.d/,

    # /etc/alternatives (core/legacy mode)
    mount options=(rw bind) /etc/alternatives/ -> /tmp/snap.rootfs_*/etc/alternatives/,

    # making all those directories slave shared.
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/alternatives/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/ssl/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/nsswitch.conf,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/apparmor/,
    mount options=(rw slave) -> /tmp/snap.rootfs_*/etc/apparmor.d/,

    # the /snap directory
    mount options=(rw rbind) /snap/ -> /tmp/snap.rootfs_*/snap/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/snap/,
    # pivot_root preparation and execution
    mount options=(rw bind) /tmp/snap.rootfs_*/var/lib/snapd/hostfs/ -> /tmp/snap.rootfs_*/var/lib/snapd/hostfs/,
    mount options=(rw private) -> /tmp/snap.rootfs_*/var/lib/snapd/hostfs/,

    # pivot_root mediation in AppArmor is not complete. See LP: #1791711.
    # However, we can mediate the new_root and put_old to be what we expect,
    # and then deny directory creation within old_root to prevent trivial
    # pivoting into a whitelisted path.
    pivot_root oldroot=/tmp/snap.rootfs_*/var/lib/snapd/hostfs/ /tmp/snap.rootfs_*/,
    # Explicitly deny creating the old_root directory in case it is
    # inadvertently added somewhere else. While this doesn't resolve
    # LP: #1791711, it provides some hardening.
    audit deny /tmp/snap.rootfs_*/{var/,var/lib/,var/lib/snapd/,var/lib/snapd/hostfs/} w,

    # cleanup
    umount /var/lib/snapd/hostfs/tmp/snap.rootfs_*/,
    umount /var/lib/snapd/hostfs/sys/,
    umount /var/lib/snapd/hostfs/dev/,
    umount /var/lib/snapd/hostfs/proc/,
    mount options=(rw rslave) -> /var/lib/snapd/hostfs/,

    # Hide /writable from view of snaps.
    mount options=(rprivate) -> /{,var/lib/snapd/hostfs/}writable/,
    umount /{,var/lib/snapd/hostfs/}writable/,

    # set up user mount namespace
    mount options=(rslave) -> /,

    # set up mount namespace for parallel instances of classic snaps
    mount options=(rw rbind) /snap/{,*/} -> /snap/{,*/},
    mount options=(rslave) -> /snap/,
    mount options=(rslave) -> /var/snap/,
    mount options=(rw rbind) /var/snap/{,*/} -> /var/snap/{,*/},
    mount options=(rw rshared) -> /var/snap/,

    # Allow reading the os-release file (possibly a symlink to /usr/lib).
    /{etc/,usr/lib/}os-release r,

    # Allow creating /var/lib/snapd/hostfs, if missing
    /var/lib/snapd/hostfs/ rw,

    # set up snap-specific private /tmp dir
    capability chown,
    /tmp/ rw,
    /tmp/snap.*/ rw,
    /tmp/snap.*/tmp/ rw,
    mount options=(rw private) ->  /tmp/,
    mount options=(rw bind) /tmp/snap.*/tmp/ -> /tmp/,
    mount fstype=devpts options=(rw) devpts -> /dev/pts/,
    mount options=(rw bind) /dev/pts/ptmx -> /dev/ptmx,     # for bind mounting
    mount options=(rw bind) /dev/pts/ptmx -> /dev/pts/ptmx, # for bind mounting under LXD
    # Workaround for LP: #1584456 on older kernels that mistakenly think
    # /dev/pts/ptmx needs a trailing '/'
    mount options=(rw bind) /dev/pts/ptmx/ -> /dev/ptmx/,
    mount options=(rw bind) /dev/pts/ptmx/ -> /dev/pts/ptmx/,

    # for running snaps on classic
    /snap/ r,
    /snap/** r,
    /snap/ r,
    /snap/** r,

    # NOTE: at this stage the /snap directory is stable as we have called
    # pivot_root already.

    # nvidia handling, glob needs /usr/** and the launcher must be
    # able to bind mount the nvidia dir
    /sys/module/nvidia/version r,
    /sys/**/drivers/nvidia{,_*}/* r,
    /sys/**/nvidia*/uevent r,
    /sys/module/nvidia{,_*}/* r,
    /dev/nvidia[0-9]* r,
    /dev/nvidiactl r,
    /dev/nvidia-uvm r,
    /usr/** r,
    mount options=(rw bind) /usr/lib{,32}/nvidia-*/ -> /{tmp/snap.rootfs_*/,}var/lib/snapd/lib/gl{,32}/,
    mount options=(rw bind) /usr/lib{,32}/nvidia-*/ -> /{tmp/snap.rootfs_*/,}var/lib/snapd/lib/gl{,32}/,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/,

    # Vulkan support
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/,

    # GLVND EGL vendor
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/{,*} w,
    mount fstype=tmpfs options=(rw nodev noexec) none -> /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/,
    mount options=(remount ro bind) -> /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/,

    # create gl dirs as needed
    /tmp/snap.rootfs_*/ r,
    /tmp/snap.rootfs_*/var/ r,
    /tmp/snap.rootfs_*/var/lib/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/gl{,32}/** rw,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/vulkan/** rw,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/ r,
    /tmp/snap.rootfs_*/var/lib/snapd/lib/glvnd/** rw,

    # for chroot on steroids, we use pivot_root as a better chroot that makes
    # apparmor rules behave the same on classic and outside of classic.

    # for creating the user data directories: ~/snap, ~/snap/<name> and
    # ~/snap/<name>/<version>
    / r,
    @{HOMEDIRS}/ r,
    # These should both have 'owner' match but due to LP: #1466234, we can't
    # yet
    @{HOME}/ r,
    @{HOME}/snap/{,*/,*/*/} rw,

    # experimental
    @{HOME}/.snap/                rw,
    @{HOME}/.snap/data/{,*/,*/*/} rw,
    @{HOME}/Snap/{,*/,*/*/}       rw,

    # Special case for *classic* snaps that are used by users with existing dirs
    # in /var/lib/. Like jenkins, postgresql, mysql, puppet, ...
    # (see https://forum.snapcraft.io/t/9717)
    # TODO: this can be removed once we support home-dirs outside of /home
    #       better
    /var/ r,
    /var/lib/ r,
    # These should both have 'owner' match but due to LP: #1466234, we can't
    # yet
    /var/lib/*/ r,
    /var/lib/*/snap/{,*/,*/*/} rw,

    # for creating the user shared memory directories
    /{dev,run}/{,shm/} r,
    # This should both have 'owner' match but due to LP: #1466234, we can't yet
    /{dev,run}/shm/{,*/,*/*/} rw,

    # for creating the user XDG_RUNTIME_DIR: /run/user, /run/user/UID and
    # /run/user/UID/<name>
    /run/user/{,[0-9]*/,[0-9]*/*/} rw,

    # Workaround https://launchpad.net/bugs/359338 until upstream handles
    # stacked filesystems generally.
    # encrypted ~/.Private and old-style encrypted $HOME
    @{HOME}/.Private/ r,
    @{HOME}/.Private/** mrwlk,
    # new-style encrypted $HOME
    @{HOMEDIRS}/.ecryptfs/*/.Private/ r,
    @{HOMEDIRS}/.ecryptfs/*/.Private/** mrwlk,

    # Allow snap-confine to move to the void, creating it if necessary.
    /var/lib/snapd/void/ rw,

    # Allow snap-confine to read snap contexts
    /var/lib/snapd/context/snap.* r,

    # Allow snap-confine to unmount stale mount namespaces.
    umount /run/snapd/ns/*.mnt,
    /run/snapd/ns/snap.*.fstab w,
    # Allow snap-confine to read and write mount namespace information files.
    /run/snapd/ns/snap.*.info rw,
    # Required to correctly unmount bound mount namespace.
    # See LP: #1735459 for details.
    umount /,

    # support for locking
    /run/snapd/lock/ rw,
    /run/snapd/lock/*.lock rwk,

    # support for the mount namespace sharing
    capability sys_ptrace,
    # allow snap-confine to read /proc/1/ns/mnt
    ptrace read peer=unconfined,
    # https://forum.snapcraft.io/t/custom-kernel-error-on-readlinkat-in-mount-namespace/6097/21
    ptrace trace peer=unconfined,

    mount options=(rw rbind) /run/snapd/ns/ -> /run/snapd/ns/,
    mount options=(private) -> /run/snapd/ns/,
    / rw,
    /run/ rw,
    /run/snapd/ rw,
    /run/snapd/ns/ rw,
    /run/snapd/ns/*.lock rwk,
    /run/snapd/ns/*.mnt rw,
    ptrace (read, readby, tracedby) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
    @{PROC}/*/mountinfo r,
    capability sys_chroot,
    capability sys_admin,
    signal (send, receive) set=(abrt) peer=/usr/lib/snapd/snap-confine,
    signal (send) set=(int) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
    signal (send, receive) set=(int, alrm, exists) peer=/usr/lib/snapd/snap-confine,
    signal (receive) set=(exists) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,

    # workaround for linux 4.13/upstream, see
    # https://forum.snapcraft.io/t/snapd-2-27-6-2-in-debian-sid-blocked-on-apparmor-in-kernel-4-13-0-1/2813/3
    ptrace (trace, tracedby) peer=/usr/lib/snapd/snap-confine,

    # Allow reading snap cookies.
    /var/lib/snapd/cookie/snap.* r,

    # For aa_change_hat() to go into ^mount-namespace-capture-helper
    @{PROC}/[0-9]*/attr/{,apparmor/}current w,

    # As a special exception allow snap-confine to write to anything in /var/lib.
    # This code should be changed to allow delegation so that snap-confine can
    # inherit any file descriptor and pass it to the invoked application but
    # this is not possible in apparmor yet.
    # See https://bugs.launchpad.net/snapd/+bug/1815869
    /var/lib/** rw,

    ^mount-namespace-capture-helper (attach_disconnected) {
        # We run privileged, so be fanatical about what we include and don't use
        # any abstractions
        /etc/ld.so.cache r,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}ld{-*,64}.so* mrix,
        # libc, you are funny
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libc{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libpthread{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libreadline{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}librt{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libgcc_s.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libncursesw{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libresolv{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libselinux.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libpcre.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libmount.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libblkid.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libuuid.so* mr,
        # normal libs in order
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libapparmor.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcgmanager.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/{,atomics/}}libdl{,-[0-9]*}.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnih-dbus.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libdbus-1.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libudev.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libseccomp.so* mr,
        /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libcap.so* mr,

        /usr/lib/snapd/snap-confine mr,

        /dev/null rw,
        /dev/full rw,
        /dev/zero rw,
        /dev/random r,
        /dev/urandom r,

        capability sys_ptrace,
        capability sys_admin,
        # This allows us to read and bind mount the namespace file
        / r,
        @{PROC}/ r,
        @{PROC}/*/ r,
        @{PROC}/*/ns/ r,
        @{PROC}/*/ns/mnt r,
        /run/ r,
        /run/snapd/ r,
        /run/snapd/ns/ r,
        /run/snapd/ns/*.mnt rw,
        # NOTE: the source name is / even though we map /proc/123/ns/mnt
        mount options=(rw bind) / -> /run/snapd/ns/*.mnt,
        # This is the SIGALRM that we send and receive if a timeout expires
        signal (send, receive) set=(alrm) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
        # Those two rules are exactly the same but we don't know if the parent process is still alive
        # and hence has the appropriate label or is already dead and hence has no label.
        signal (send) set=(exists) peer=/usr/lib/snapd/snap-confine,
        signal (send) set=(exists) peer=unconfined,
        # This is so that we can abort
        signal (send, receive) set=(abrt) peer=/usr/lib/snapd/snap-confine//mount-namespace-capture-helper,
        #  This is the signal we get if snap-confine dies (we subscribe to it with prctl)
        signal (receive) set=(int) peer=/usr/lib/snapd/snap-confine,
        # This allows snap-confine to be killed from the outside.
        signal (receive) peer=unconfined,
        # This allows snap-confine to wait for us
        ptrace (read, trace, tracedby) peer=/usr/lib/snapd/snap-confine,
    }

    # Allow snap-confine to be killed
    signal (receive) peer=unconfined,

    # Allow switching to snap-update-ns with a per-snap profile.
    change_profile -> snap-update-ns.*,

    # Allow executing snap-update-ns when...

    # ...snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the distribution package. This is also the location used when using
    # the core/base snap on all-snap systems. The variants here represent
    # various locations of libexecdir across distributions.
    /usr/lib{,exec,64}/snapd/snap-update-ns r,

    # ...snap-confine is not, conceptually, re-executing and uses
    # snap-update-ns from the distribution package but we are already inside
    # the constructed mount namespace so we must traverse "hostfs". The
    # variants here represent various locations of libexecdir across
    # distributions.
    /var/lib/snapd/hostfs/usr/lib{,exec,64}/snapd/snap-update-ns r,

    # ..snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the core or snapd snaps. Note that the location of the actual snap
    # varies from distribution to distribution. The variants here represent
    # different locations of snap mount directory across distributions.
    /{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-update-ns r,

    # ...snap-confine is, conceptually, re-executing and uses snap-update-ns
    # from the core snap or snapd snap, but we are already inside the
    # constructed mount namespace. Here the apparmor kernel module
    # re-constructs the path to snap-update-ns using the "hostfs" mount entry
    # rather than the more "natural" /snap mount entry but we have no control
    # over that.  This is reported as (LP: #1716339). The variants here
    # represent different locations of snap mount directory across
    # distributions.
    /var/lib/snapd/hostfs/{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-update-ns r,

    # Allow executing snap-discard-ns, just like the set for snap-update-ns
    # above but with the key difference that snap-discard-ns does not
    # have a dedicated profile so we need to inherit snap-confine's profile.

    /usr/lib{,exec,64}/snapd/snap-discard-ns rix,
    /var/lib/snapd/hostfs/usr/lib{,exec,64}/snapd/snap-discard-ns rix,
    /{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-discard-ns rix,
    /var/lib/snapd/hostfs/{,var/lib/snapd/}snap/{core,snapd}/*/usr/lib/snapd/snap-discard-ns rix,

    # Allow mounting /var/lib/jenkins from the host into the snap.
    mount options=(rw rbind) /var/lib/jenkins/ -> /tmp/snap.rootfs_*/var/lib/jenkins/,
    mount options=(rw rslave) -> /tmp/snap.rootfs_*/var/lib/jenkins/,

    # Suppress noisy file_inherit denials (LP: #1850552) until LP: #1849753 is
    # fixed.
    deny /dev/shm/.org.chromium.Chromium.* rw,

    # While snap-confine itself doesn't require unix rules and therefore all
    # unix rules are implicitly denied, adding an explicit deny for unix to
    # silence noisy denials breaks nested lxd. Until the cause is determined,
    # do not use an explicit deny for unix. (LP: #1855355)
    #deny unix,

    # Explicitly deny these accesses which show up on Arch to silence the
    # denials for this unneeded access.
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_files-[0-9]*.so* mr,
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_mymachines.[0-9]*.so* mr,
    deny /{,usr/}lib{,32,64,x32}/{,@{multiarch}/}libnss_systemd.[0-9]*.so* mr,
    deny /etc/nsswitch.conf r,
    deny /etc/passwd r,
}
}
$ ls -l /var/lib/snapd/apparmor/snap-confine
total 8
-rw-r--r-- 1 root root  17 avril 19 12:08 cap-bpf
-rw-r--r-- 1 root root 174 mai    6 15:06 nfs-support

I’ll bet this is your issue. I think you need to allow root to access the home folders as root (i.e. not squashed as this line indicates your export currently is configured) or snaps will fail IIRC.

Try ensuring that your home folders are world readable/executable then, so that root can still access them when squashed to nfsnobody. You might be able to use ACLs to limit the exposure a bit more than world r-x by adding an entry for nfsnobody. We’re veering away from my expertise tho, so I’ll defer to others who might understand NFS permissions better than I.