mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-05 12:16:44 +02:00
On macOS the incubator went through /usr/bin/login -pq <user> <shell> -c <cmd> for any session, including non-TTY 'ssh host cmd' exec sessions. /usr/bin/login does not propagate the child command's exit status when invoked this way: it exits 0 once the child has been spawned, so 'ssh mac exit 42' returned 0 instead of 42 and 'ssh mac /nonexistent/binary' returned 0 instead of 127. The exit-status frame ordering fix in this branch is still required (the server has to send the right frames in the right order), but it is not sufficient on its own when the value being sent is wrong. For interactive shells (hasTTY) login still gives us the desired PAM 'remote' session and utmpx accounting, and exit-code propagation is not user-observable, so the login path is kept. For non-TTY command exec sessions we now fall through to handleSSHInProcess, which uses dropPrivileges + cmd.Run + os.Exit(code) — the same path Linux already uses for non-TTY sessions, and the path that produces correct exit codes in the integration tests. Verified against the macOS CI logs from run 25326829991: the artifact shows the server sending exit-status 0 from /usr/bin/login -pq ... /bin/bash -c 'exit 42', confirming the diagnosis. Verified on Linux that the fall-through path produces the right exit codes (integration tests pass 5x consecutively on the full incubator path including drop-privileges). Fixes #18256 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>