From: Lennart Poettering Date: Tue, 31 Oct 2023 14:30:12 +0000 (+0100) Subject: nspawn: fix barriers when wiping fully visible procfs/sysfs X-Git-Tag: v255-rc1~64^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1a8d781495c91c3bf62bf87190af4470a44ba8a5;p=thirdparty%2Fsystemd.git nspawn: fix barriers when wiping fully visible procfs/sysfs 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 --- diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 37a75134f92..9e63a355ac3 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -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