snap-confine
Folders and files
Name | Name | Last commit date | ||
---|---|---|---|---|
parent directory.. | ||||
= Mount namespace setup in snap-confine = This document provides a terse explanation of the mount setup using syscall traces to show precisely what is happening and show the difference between all snaps images and classic. Obtain traces with (ignoring select helps keep strace from hanging): $ sudo snap install hello-world $ sudo /usr/lib/snapd/snap-discard-ns hello-world $ sudo strace -f -vv -s8192 -o /tmp/trace.unshare -e trace='!select' /snap/bin/hello-world $ sudo strace -f -vv -s8192 -o /tmp/trace.setns -e trace='!select' /snap/bin/hello-world Examine /tmp/trace.unshare for initial mount namespace setup and /tmp/trace.setns for seeing how the mount namespace is reused on subsequent runs. Note that running /usr/lib/snapd/snap-discard-ns prior to running the command is required for creating the new mount namespace (otherwise the previous mount namespace will be reused). = Mount namespace setup in detail = Here are the steps snap-confine takes when setting up the mount namespace for a given snap: # Create the /run/snapd/ns directory to save off the mount namespace to be # shared on other app-invocations open("/", O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC) = 3 mkdirat(3, "run", 0755) = -1 EEXIST (File exists) openat(3, "run", O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC) = 4 mkdirat(4, "snapd", 0755) = -1 EEXIST (File exists) openat(4, "snapd", O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC) = 3 mkdirat(3, "ns", 0755) = -1 EEXIST (File exists) openat(3, "ns", O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC) = 4 # If /run/snapd/ns/<snap name>.mnt exists, enter that namespace: openat(3, "hello-world.mnt", O_RDONLY|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0600) = 5 fstatfs(5, {f_type=0x6e736673, ...) = 0 setns(5, CLONE_NEWNS) = 0 ... mount namespace setup finished, go on to setup the rest of the sandbox ... # Otherwise, create a new mount namespace unshare(CLONE_NEWNS) mount("none", "/", NULL, MS_REC|MS_SLAVE, NULL) = 0 # Classic-only - mount rootfs in the namespace mkdir("/tmp/snap.rootfs_HkQghZ", 0700) = 0 mount("/snap/ubuntu-core/current", "/tmp/snap.rootfs_HkQghZ", NULL, MS_BIND, NULL) = 0 # Classic only - mount directories from host over rootfs mount("/dev", "/tmp/snap.rootfs_HkQghZ/dev", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/etc", "/tmp/snap.rootfs_HkQghZ/etc", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/home", "/tmp/snap.rootfs_HkQghZ/home", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/root", "/tmp/snap.rootfs_HkQghZ/root", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/proc", "/tmp/snap.rootfs_HkQghZ/proc", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/sys", "/tmp/snap.rootfs_HkQghZ/sys", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/tmp", "/tmp/snap.rootfs_HkQghZ/tmp", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/var/snap", "/tmp/snap.rootfs_HkQghZ/var/snap", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/var/lib/snapd", "/tmp/snap.rootfs_HkQghZ/var/lib/snapd", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/var/tmp", "/tmp/snap.rootfs_HkQghZ/var/tmp", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/run", "/tmp/snap.rootfs_HkQghZ/run", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/media", "/tmp/snap.rootfs_HkQghZ/media", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/lib/modules", "/tmp/snap.rootfs_HkQghZ/lib/modules", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/usr/src", "/tmp/snap.rootfs_HkQghZ/usr/src", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/var/log", "/tmp/snap.rootfs_HkQghZ/var/log", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/snap", "/tmp/snap.rootfs_HkQghZ/snap", NULL, MS_BIND|MS_REC|MS_SLAVE, NULL) = 0 mount("/snap/ubuntu-core/current/etc/alternatives", "/tmp/snap.rootfs_HkQghZ/etc/alternatives", NULL, MS_BIND|MS_SLAVE, NULL) = 0 mount("/", "/tmp/snap.rootfs_HkQghZ/var/lib/snapd/hostfs", NULL, MS_RDONLY|MS_BIND, NULL) = 0 # Classic only - pivot_root into the rootfs pivot_root(".", ".") = 0 umount2(".", MNT_DETACH) = 0 # Create a bind-mounted private /tmp mkdir("/tmp/snap.0_snap.hello-world.hello-world_QXGSt1", 0700) = 0 mkdir("/tmp/snap.0_snap.hello-world.hello-world_QXGSt1/tmp", 01777) = 0 mount("/tmp/snap.0_snap.hello-world.hello-world_QXGSt1/tmp", "/tmp", NULL, MS_BIND, NULL) = 0 mount("none", "/tmp", NULL, MS_PRIVATE, NULL) = 0 # Create a per-snap /dev/pts mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, "newinstance,ptmxmode=0666,mode=0"...) mount("/dev/pts/ptmx", "/dev/ptmx", 0x5574dfe9a5c3, MS_BIND, NULL) # Process snap-defined mounts (eg, for content interface, mount the source to # the target as defined in /var/lib/snapd/mount/snap.<name>.<command>.fstab) # Eg: mount("/snap/some-content-snap/current/src", "/snap/hello-world/current/dst", NULL, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_BIND, NULL) # Bind mount this namespace to the application-specific NSFS magic file to # preserve it across snap invocations (an fchdir() happened just after the # unshare(), above). mount("/proc/12887/ns/mnt", "hello-world.mnt", NULL, MS_BIND, NULL) = 0 ... mount namespace setup finished, go on to setup the rest of the sandbox ...