diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 700fba5cba..0a87c5ec77 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1901,14 +1901,21 @@ int namespace_fork_full( /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that - * /proc/self/fd works correctly. */ + * /proc/self/fd works correctly. + * + * TODO: once we can rely on PIDFD_INFO_EXIT, do not keep the middle process around and instead + * return the pidfd of the inner process for direct tracking. */ + + /* Insist on PDEATHSIG being enabled, as the pid returned is the one of the middle man, and otherwise + * killing of it won't be propagated to the inner child. */ + assert((flags & (FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) != 0); + assert((flags & (FORK_DETACH|FORK_FREEZE)) == 0); assert(!FLAGS_SET(flags, FORK_ALLOW_DLOPEN)); /* never allow loading shared library from another ns */ r = pidref_safe_fork_full( outer_name, - NULL, - except_fds, n_except_fds, - (flags|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), + /* stdio_fds = */ NULL, /* except_fds = */ NULL, /* n_except_fds = */ 0, + (flags|FORK_DEATHSIG_SIGKILL) & ~(FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS|FORK_CLOSE_ALL_FDS|FORK_PACK_FDS|FORK_CLOEXEC_OFF|FORK_RLIMIT_NOFILE_SAFE), ret); if (r < 0) return r; @@ -1928,7 +1935,7 @@ int namespace_fork_full( inner_name, NULL, except_fds, n_except_fds, - flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO), + flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_REARRANGE_STDIO|FORK_FLUSH_STDIO|FORK_STDOUT_TO_STDERR), &pidref_inner); if (r < 0) _exit(EXIT_FAILURE); @@ -1939,6 +1946,11 @@ int namespace_fork_full( return 0; } + log_close(); + log_set_open_when_needed(true); + + (void) close_all_fds(&pidref_inner.fd, 1); + r = pidref_wait_for_terminate_and_check( inner_name, &pidref_inner,