diff --git a/src/bin/login.rs b/src/bin/login.rs index f7f337a5ed..5e28e50733 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -154,6 +154,22 @@ pub fn main() { continue; } Some(user) => { + // Establish a working directory on the `file` scheme (the + // user's home) BEFORE any namespace restriction. login runs + // with the CWD inherited from init, which on the live image + // lives on the `initfs` scheme. apply_login_schemes() below + // switches to a namespace containing only DEFAULT_SCHEMES + // (which excludes `initfs`), after which that inherited CWD + // fd is unresolvable — and because relibc resolves paths via + // the CWD fd (AT_REDOX_CWD_FD), the login shell's spawn + // (Command child chdir + execve) then fails or hangs. Doing + // this chdir here, while still in the full namespace, points + // the CWD at `file:` (home, fallback `/`), which remains + // valid inside the restricted login namespace. + if std::env::set_current_dir(&user.home).is_err() { + let _ = std::env::set_current_dir("/"); + } + if user.is_passwd_blank() { if let Ok(mut motd) = File::open(MOTD_FILE) { io::copy(&mut motd, &mut stdout).r#try(&mut stderr);