tailscale/flakehashes.json
Kristoffer Dalby 4fd5bcc2b8 ssh/tailssh: fix exit-status ordering and improve session shutdown
Fix a race where CloseWrite (SSH_MSG_CHANNEL_EOF) could be sent before
Exit (exit-status), causing SSH clients (especially on macOS) to miss
the exit status. The root cause was a select between outputDone and
ctx.Done that allowed Exit to be called while stdout was still copying,
or after CloseWrite had already been sent.

Replace the atomic.Bool/atomic.Int32/channel synchronization with
sync.WaitGroup and guarantee the wire ordering required by RFC 4254
section 6.10: exit-status -> EOF -> CHANNEL_CLOSE.

The new ordering in run():
1. cmd.Wait() returns with exit code
2. ss.Exit(exitCode) sends exit-status
3. closeAll(childPipes) signals io.Copy goroutines to finish
4. wg.Wait() waits for stdout goroutine which calls CloseWrite (EOF)
5. defer ss.Close() sends CHANNEL_CLOSE on function return

Additional changes:
- Send SIGHUP instead of SIGKILL on session termination
- Use exit code 255 for SSH protocol/permission errors
- Use exit code 127 for command not found
- Use exit code 254 for recording failures
- Add isNotFoundOrExecutable helper

Based on tailscale/tailscale#18331.

Fixes #18256

Change-Id: Ib0c984d466c1a96c8f642e94a5dfe60d33d71fd8
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2026-05-04 11:29:41 +00:00

11 lines
300 B
JSON

{
"toolchain": {
"rev": "dfe2a5fd8ee2e68b08ce5ff259269f50ecadf2f4",
"sri": "sha256-pCvFNTFuvhSBb5O+PPuilaowP4tXcCOP1NgYUDJTcJU="
},
"vendor": {
"goModSum": "sha256-gyNEKCCFTtvRVkcavNxRd6laPOJ9CvdiTQyL4bLHyco=",
"sri": "sha256-jdsGXGI6v+uaC9rWZT30WEngV9HHSHbg/kNKje4U0Uk="
}
}