The username is read with the liner line editor, which puts the console
pty into raw mode (ICANON/ECHO cleared) and does not restore it. In raw
mode the pty line discipline never flushes a completed line into the
slave read buffer the way a shell's canonical read_line expects, so the
interactive shell (brush) never receives a typed command even though
getty forwards it to the pty master. Reset stdin to sane cooked settings
(ICANON|ECHO|ISIG, ICRNL, OPOST|ONLCR, VMIN=1/VTIME=0) via tcsetattr
before spawning the shell.
The login name is read via the liner line editor, which puts the console
fd into non-blocking (and raw) mode and does not restore it. The shell
inherits fd 0; an interactive shell doing blocking line reads on a
non-blocking pty slave never receives forwarded input (reads return
empty), so the shell can never run a command. Clear O_NONBLOCK on
stdin/stdout/stderr in spawn_shell before spawning. Restores the login
namespace restriction (skipping it did not affect the symptom).
Getty forwards console input to the pty master correctly (verified), and
login reads the username fine, but after apply_login_schemes() restricts
the namespace the interactive shell's pty-slave read never returns the
forwarded input. Temporarily skip the restriction to confirm it is the
cause. Also removes the getty forward diagnostic.
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.
The real fix is in init (no longer leaves an initfs-scheme CWD that is
invalid in the restricted login namespace), so spawn_shell can stay
minimal again.
After apply_login_schemes() swaps into the restricted login namespace
(only DEFAULT_SCHEMES), the CWD inherited from init on the live image is
/scheme/initfs, whose scheme is NOT in that namespace. File operations
that consult the CWD fd (notably the child's execve opening the shell
binary) then block, so the login shell never starts. chdir to the user's
home (fallback /), both on the always-present 'file' scheme, before
spawning. Also drops the temporary spawn_shell diagnostics.
Probe the shell binary and home directory in the (possibly restricted)
login namespace before spawning, and print the exact spawn error with
raw_os_error. This isolates whether a failed login shell spawn is due to
a missing binary, an unreachable cwd/home, or an exec-time error.
grantpt() and unlockpt() need to be used according to the standard, even
though our grantpt is a no-op (since we auto-lock ptys as we give them
out).
This is part of my series for ptyd. This can be safely merged as long as
the relibc/ and base/ changes are merged at the same time.
Previously root would need to know its own password. On Linux root can
change its own password without needing to enter its own password. It
can do so on Redox OS already anyway by directly editing /etc/shadow.
This daemon will request the password of the user, check that the user
is in the sudo group and if everything checks out elevate the sudo
process to root after which the sudo process can exec the target process.