Don't expose /etc/alternatives from the host #50

Merged
merged 4 commits into from Jun 28, 2016
@@ -0,0 +1,15 @@
+summary: Regression check for https://bugs.launchpad.net/snap-confine/+bug/1580018
+# This is blacklisted on debian because we first have to get the dpkg-vendor patches
+systems: [-debian-8]
+execute: |
+ cd /
+ echo "Having installed the snapd-hacker-toolbelt snap"
+ snap list | grep -q snapd-hacker-toolbelt || snap install snapd-hacker-toolbelt
+
+ echo "We can check the inode number of /etc/alternatives"
+ host_inode="$(stat -c '%i' /etc/alternatives)"
+ core_inode="$(stat -c '%i' /snap/ubuntu-core/current/etc/alternatives)"
+ effective_inode="$(/snap/bin/snapd-hacker-toolbelt.busybox stat -c '%i' /etc/alternatives)"
+ echo "The inode number as seen from a confined snap should be that of the /etc/alternatives from the core snap"
+ [ "$host_inode" != "$core_inode" ]
+ [ "$effective_inode" = "$core_inode" ]
View
@@ -215,6 +215,24 @@ void setup_snappy_os_mounts()
die("cannot bind mount %s to %s", src, dst);
}
}
+ // Since we mounted /etc from the host above, we need to put
+ // /etc/alternatives from the os snap back.
+ // https://bugs.launchpad.net/snap-confine/+bug/1580018
+ const char *etc_alternatives = "/etc/alternatives";
+ if (access(etc_alternatives, F_OK) == 0) {
+ char src[512];
+ char dst[512];
+ must_snprintf(src, sizeof src, "%s%s", core_snap_dir,
+ etc_alternatives);
+ must_snprintf(dst, sizeof dst, "%s%s", rootfs_dir,
+ etc_alternatives);
+ debug("bind mounting %s to %s", src, dst);
+ // NOTE: MS_SLAVE so that the started process cannot maliciously mount
+ // anything into those places and affect the system on the outside.
+ if (mount(src, dst, NULL, MS_BIND | MS_SLAVE, NULL) != 0) {
+ die("cannot bind mount %s to %s", src, dst);
+ }
+ }
#ifdef NVIDIA_ARCH
// Make this conditional on Nvidia support for Arch as Ubuntu doesn't use
// this so far and it requires a very recent version of the core snap.
@@ -252,7 +270,9 @@ void setup_snappy_os_mounts()
// passwd,groups} is in sync between the two systems (probably via
// selected bind mounts of those files).
const char *mounts[] =
- { "/bin", "/sbin", "/lib", "/lib32", "/libx32", "/lib64", "/usr" };
+ { "/bin", "/sbin", "/lib", "/lib32", "/libx32", "/lib64", "/usr",
+ "/etc/alternatives"
+ };
for (int i = 0; i < sizeof(mounts) / sizeof(char *); i++) {
// we mount the OS snap /bin over the real /bin in this NS
const char *dst = mounts[i];