]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: fix barriers when wiping fully visible procfs/sysfs
authorLennart Poettering <lennart@poettering.net>
Tue, 31 Oct 2023 14:30:12 +0000 (15:30 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 31 Oct 2023 14:33:49 +0000 (15:33 +0100)
Let's wait until the child is fully done with mounting it's own
instances of procfs/sysfs before we destroy our fully visible copies of
it.

This borrows heavily from Christian Brauners fix #29521, but splits the
place + sync into two steps so that the child payload is not started
before the parent has destroyed the procfs instance.

Alternative to: #29521
Fixes: #28157
src/nspawn/nspawn.c

index 37a75134f9246dcd561aac7aa20d7e97470591bf..9e63a355ac3242200ac1c1ca075823fc1f298e4f 100644 (file)
@@ -3516,9 +3516,7 @@ static int inner_child(
         if (!env_use)
                 return log_oom();
 
-        /* Let the parent know that we are ready and
-         * wait until the parent is ready with the
-         * setup, too... */
+        /* Let the parent know that we are ready and wait until the parent is ready with the setup, too... */
         if (!barrier_place_and_sync(barrier)) /* #5 */
                 return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Parent died too early");
 
@@ -5136,6 +5134,11 @@ static int run_container(
         if (r < 0)
                 return r;
 
+        /* Wait that the child is completely ready now, and has mounted their own copies of procfs and so on,
+         * before we take the fully visible instances away. */
+        if (!barrier_sync(&barrier)) /* #5.1 */
+                return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Child died too early.");
+
         if (arg_userns_mode != USER_NAMESPACE_NO) {
                 r = wipe_fully_visible_fs(mntns_fd);
                 if (r < 0)
@@ -5143,8 +5146,9 @@ static int run_container(
                 mntns_fd = safe_close(mntns_fd);
         }
 
-        /* Let the child know that we are ready and wait that the child is completely ready now. */
-        if (!barrier_place_and_sync(&barrier)) /* #5 */
+        /* And now let the child know that we completed removing the procfs instances, and it can start the
+         * payload. */
+        if (!barrier_place(&barrier)) /* #5.2 */
                 return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Child died too early.");
 
         /* At this point we have made use of the UID we picked, and thus nss-systemd/systemd-machined.service