login: chdir to home (file scheme) before restricting the namespace
The login shell spawn was failing/hanging because login inherits its CWD from init, which on the live image is on the 'initfs' scheme. apply_login_schemes() switches to a namespace with only DEFAULT_SCHEMES (no 'initfs'), leaving that inherited CWD fd unresolvable; relibc resolves paths through the CWD fd (AT_REDOX_CWD_FD), so the shell child's chdir + execve then fail with ENOENT (getty respawns login in a loop) or hang. chdir into the user's home (on the always-present 'file' scheme, fallback '/') while still in the full namespace, so the CWD fd stays valid after the restriction and the shell spawns.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user