summaryrefslogtreecommitdiffhomepage
path: root/control/controlhttp/controlhttpserver/controlhttpserver.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2026-04-05 13:47:51 +0000
committerBrad Fitzpatrick <brad@danga.com>2026-04-07 05:31:16 -0700
commit2b1cfa7c4d55a438062cef08ae5f85e0ffad5305 (patch)
tree830c65bad6bb057567e56548eced947cbeab2ae3 /control/controlhttp/controlhttpserver/controlhttpserver.go
parent6e44c6828b501724b72a1bb31e51677b9e9f740b (diff)
downloadtailscale-2b1cfa7c4d55a438062cef08ae5f85e0ffad5305.tar.xz
tailscale-2b1cfa7c4d55a438062cef08ae5f85e0ffad5305.zip
ssh/tailssh: fix race in session termination message delivery
When a recording upload fails mid-session, the recording goroutine cancels the session context. This triggers two concurrent paths: exec.CommandContext kills the process (causing cmd.Wait to return), and killProcessOnContextDone tries to write the termination message via exitOnce.Do. If cmd.Wait returns first, the main goroutine's exitOnce.Do(func(){}) steals the once, and the termination message is never written to the client. Fix by waiting for killProcessOnContextDone to finish writing the termination message (via <-ss.exitHandled) before claiming exitOnce, when the context is already done. Also fix the fallback path when launchProcess itself fails due to context cancellation: use SSHTerminationMessage() with the correct "\r\n\r\n" framing instead of fmt.Fprintf with the internal error string. Deflakes TestSSHRecordingCancelsSessionsOnUploadFailure, which was failing consistently at a low rate due to the exitOnce race. After this fix, flakestress passes with 8,668 runs, 0 failures. Fixes #7707 (again. hopefully for good.) Change-Id: I5ab911c71574db8d3f9d979fb839f273be51ecf9 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'control/controlhttp/controlhttpserver/controlhttpserver.go')
0 files changed, 0 insertions, 0 deletions