diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 4f935c1439..183442aef3 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -4133,12 +4133,22 @@ static int apply_root_directory( assert(exit_status); if (params->flags & EXEC_APPLY_CHROOT) - if (!needs_mount_ns && context->root_directory) + if (!needs_mount_ns && context->root_directory) { if (chroot(runtime->ephemeral_copy ?: context->root_directory) < 0) { *exit_status = EXIT_CHROOT; return -errno; } + /* chroot(2) changes only the process root, not cwd. Move cwd into the new root + * immediately so that a subsequent apply_working_directory() failure that is + * silently ignored via working_directory_missing_ok cannot leave cwd pointing + * at a pre-chroot dentry outside the new root. */ + if (chdir("/") < 0) { + *exit_status = EXIT_CHROOT; + return -errno; + } + } + return 0; }