Permalink
Browse files

Enable snap-confine namespace sharing

This patch changes mount-support.[ch] a little so that there's no
explicit unshare API anymore (this is handled by ns-support.h) and so
that mount-suppor.h is really just about populating the namespace that
is already provided.

In addition, sc-main.c now uses SNAP_NAME to join or create a namespace
group and if populates it if necessary. The apparmor profile is updated
to let snap-confine perform the additional tasks.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
  • Loading branch information...
1 parent 2b7050e commit 865c5dfb9704d71c16fafc2cf42ef95c1fd2933e @zyga zyga committed Sep 8, 2016
Showing with 86 additions and 31 deletions.
  1. +5 −15 src/mount-support.c
  2. +0 −14 src/mount-support.h
  3. +16 −2 src/sc-main.c
  4. +65 −0 src/snap-confine.apparmor.in
View
@@ -422,21 +422,6 @@ static bool __attribute__ ((used))
return false;
}
-void sc_unshare_mount_ns()
-{
- // NOTE: unshare() and CLONE_NEWNS require linux >= 2.6.16 and glibc >=
- // 2.14 if using an older glibc, you'd need -D_BSD_SOURCE or
- // -D_SVID_SORUCE.
- if (unshare(CLONE_NEWNS) < 0) {
- die("unable to set up mount namespace");
- }
- // Make our "/" a rslave of the real "/". this means that mounts from the
- // host "/" get propagated to our namespace (i.e. we see new media mounts).
- if (mount("none", "/", NULL, MS_REC | MS_SLAVE, NULL) != 0) {
- die("can not make make / rslave");
- }
-}
-
void sc_populate_mount_ns(const char *security_tag)
{
// Get the current working directory before we start fiddling with
@@ -447,6 +432,11 @@ void sc_populate_mount_ns(const char *security_tag)
if (vanilla_cwd == NULL) {
die("cannot get the current working directory");
}
+ // Make our "/" a rslave of the real "/". this means that mounts from the
+ // host "/" get propagated to our namespace (i.e. we see new media mounts).
+ if (mount("none", "/", NULL, MS_REC | MS_SLAVE, NULL) != 0) {
+ die("can not make make / rslave");
+ }
// do the mounting if run on a non-native snappy system
if (is_running_on_classic_distribution()) {
setup_snappy_os_mounts();
View
@@ -18,20 +18,6 @@
#ifndef SNAP_MOUNT_SUPPORT_H
#define SNAP_MOUNT_SUPPORT_H
-/**
- * Unshare the mount namespace.
- *
- * Ensure we run in our own slave mount namespace, this will create a new mount
- * namespace and make it a slave of "/"
- *
- * Note that this means that no mount actions inside our namespace are
- * propagated to the main "/". We need this both for the private /tmp we create
- * and for the bind mounts we do on a classic distribution system.
- *
- * This also means you can't run an automount daemon under this launcher.
- **/
-void sc_unshare_mount_ns();
-
/**
* Assuming a new mountspace, populate it accordingly.
*
View
@@ -36,6 +36,7 @@
#include "udev-support.h"
#include "cleanup-funcs.h"
#include "user-support.h"
+#include "ns-support.h"
#include "quirks.h"
int sc_main(int argc, char **argv)
@@ -78,8 +79,21 @@ int sc_main(int argc, char **argv)
#endif // ifdef HAVE_SECCOMP
if (geteuid() == 0) {
- sc_unshare_mount_ns();
- sc_populate_mount_ns(security_tag);
+ const char *group_name = getenv("SNAP_NAME");
+ if (group_name == NULL) {
+ die("SNAP_NAME is not set");
+ }
+ sc_initialize_ns_groups();
+ struct sc_ns_group *group = NULL;
+ group = sc_open_ns_group(group_name);
+ sc_lock_ns_mutex(group);
+ sc_create_or_join_ns_group(group);
+ if (sc_should_populate_ns_group(group)) {
+ sc_populate_mount_ns(security_tag);
+ sc_preserve_populated_ns_group(group);
+ }
+ sc_unlock_ns_mutex(group);
+ sc_close_ns_group(group);
struct snappy_udev udev_s;
if (snappy_udev_init(security_tag, &udev_s) == 0)
setup_devices_cgroup(security_tag, &udev_s);
@@ -186,4 +186,69 @@
mount options=(rw rbind nodev nosuid noexec) /var/lib/snapd/hostfs/var/lib/lxd/ -> /var/lib/lxd/,
/var/lib/lxd/ w,
/var/lib/snapd/hostfs/var/lib/lxd r,
+
+ # support for the mount namespace sharing
+ 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,
+ owner @{PROC}/*/mountinfo r,
+ capability sys_chroot,
+ capability sys_admin,
+ signal (send) set=("int") peer=@LIBEXECDIR@//mount-namespace-capture-helper,
+
+ ^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,
+ /lib/@{multiarch}/ld-*.so mr,
+ # libc, you are funny
+ /lib/@{multiarch}/libc{,-[0-9]*}.so* mr,
+ /lib/@{multiarch}/libpthread{,-[0-9]*}.so* mr,
+ /lib/@{multiarch}/librt{,-[0-9]*}.so* mr,
+ /lib/@{multiarch}/libgcc_s.so* mr,
+ # normal libs in order
+ /lib/@{multiarch}/libapparmor.so* mr,
+ /lib/@{multiarch}/libcgmanager.so* mr,
+ /lib/@{multiarch}/libnih.so* mr,
+ /lib/@{multiarch}/libnih-dbus.so* mr,
+ /lib/@{multiarch}/libdbus-1.so* mr,
+ /lib/@{multiarch}/libudev.so* mr,
+ /usr/lib/@{multiarch}/libseccomp.so* mr,
+ /lib/@{multiarch}/libseccomp.so* mr,
+
+ @LIBEXECDIR@/snap-confine r,
+
+ /dev/null rw,
+ /dev/full rw,
+ /dev/zero rw,
+ /dev/random r,
+ /dev/urandom r,
+
+ capability sys_ptrace,
+ capability sys_admin,
+ / r,
+ owner @{PROC}/ r,
+ owner @{PROC}/*/ r,
+ owner @{PROC}/*/ns/ r,
+ owner @{PROC}/*/ns/mnt r,
+ /run/ r,
+ /run/snapd/ r,
+ /run/snapd/ns/ r,
+ /run/snapd/ns/*.mnt rw,
+ # mount options=(rw bind) /proc/*/ns/mnt/ -> /run/snapd/ns/*.mnt/,
+ mount options=(rw bind) -> /run/snapd/ns/*.mnt,
+ signal (receive) peer=unconfined,
+ signal (receive) set=("int") peer=@LIBEXECDIR@//mount-namespace-capture-helper,
+ ptrace (tracedby) peer=@LIBEXECDIR@/snap-confine,
+ ptrace,
+ }
+
+ # Allow snap-confine to be killed
+ signal (receive) peer=unconfined,
}

0 comments on commit 865c5df

Please sign in to comment.