]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: disconnect mounts propagation from host on our container dir
authorLennart Poettering <lennart@poettering.net>
Thu, 2 Mar 2023 17:28:37 +0000 (18:28 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 3 Mar 2023 11:17:42 +0000 (12:17 +0100)
@brauner noticed that in invoked containers the root directory is set to
still receive mounts from the host. We should disable that, and
guarantee we live in our own world, because that's what an
(nspawn-style) container *is* after all: a whole new world.

This hence mounts the container subtree to MS_PRIVATE after getting the
root dir in place. Note that this will later be set to MS_SHARED again.
The MS_PRIVATE disconnects mounts from the host, the MS_SHARED then
establishes a new peer group for mount propagation events, so that
payload service managers (such as systemd) can take benefit of
propagation further down the tree.

src/nspawn/nspawn.c

index db9e3b12c70ff4aa076ddd553f6e74f6bd3b5e0a..13d744870db49b98f6b2ace786079130f9a05e78 100644 (file)
@@ -3758,6 +3758,19 @@ static int outer_child(
                 directory = "/run/systemd/nspawn-root";
         }
 
+        /* Make sure we always have a mount that we can move to root later on. */
+        r = make_mount_point(directory);
+        if (r < 0)
+                return r;
+
+        /* So the whole tree is now MS_SLAVE, i.e. we'll still receive mount/umount events from the host
+         * mount namespace. For the directory we are going to run our container let's turn this off, so that
+         * we'll live in our own little world from now on, and propagation from the host may only happen via
+         * the mount tunnel dir, or not at all. */
+        r = mount_follow_verbose(LOG_ERR, NULL, directory, NULL, MS_PRIVATE|MS_REC, NULL);
+        if (r < 0)
+                return r;
+
         r = setup_pivot_root(
                         directory,
                         arg_pivot_root_new,
@@ -3815,11 +3828,6 @@ static int outer_child(
         if (r < 0)
                 return r;
 
-        /* Make sure we always have a mount that we can move to root later on. */
-        r = make_mount_point(directory);
-        if (r < 0)
-                return r;
-
         if (arg_userns_mode != USER_NAMESPACE_NO &&
             IN_SET(arg_userns_ownership, USER_NAMESPACE_OWNERSHIP_MAP, USER_NAMESPACE_OWNERSHIP_AUTO) &&
             arg_uid_shift != 0) {