Remove mount points from peer group just before oldroot unmount.
With -K (skip_private_remount) option, there could
be shared mount points under the oldroot.
So, unmounting oldroot triggers unmounting mount
points under the shared mount points, which will be
propagated to the original namespace and corresponding
mount points will be unmounted in those namespaces,
too.
To prevent such unexpected unmounting, this CL remove
mount points being unmounted from peer groups.
Bug: 27689605
TEST=Set up mount points; \
minijail0 -v -K -b /bin,/bin -P $CONTAINER -- \
/bin/true; \
Make sure shared mount points are untouched in \
the original namespace.
Change-Id: I3dbf7de2a63382c084e4d7e4c2675cc2a6f73c77
diff --git a/libminijail.c b/libminijail.c
index be6da23..fc3368a 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -1118,6 +1118,17 @@
*/
if (fchdir(oldroot))
pdie("failed to fchdir to old /");
+
+ /*
+ * If j->flags.skip_remount_private is enabled, there could be a shared
+ * mount point under |oldroot|. In such a case, mount points under the
+ * shared mount point will be unmount(2)'ed below, so that it is
+ * propagated to the original mount namespace. To prevent such
+ * unexpected unmounting, remove them from peer groups by recursive
+ * PRIVATE marking.
+ */
+ if (mount(NULL, ".", NULL, MS_REC | MS_PRIVATE, NULL))
+ pdie("failed to mount(/, private) for unmount(/)");
/* The old root might be busy, so use lazy unmount. */
if (umount2(".", MNT_DETACH))
pdie("umount(/)");