ssh/tailssh: fix race in errors returned when starting recorder

There were two code paths that could fail depending on how fast
the recorder responses. This fixes that by returning the correct
error from both paths.

Fixes #7707

Signed-off-by: Maisem Ali <maisem@tailscale.com>
(cherry picked from commit e04acabfde4ce218d5800bbf8c61bf3309d2a0bb)
This commit is contained in:
Maisem Ali 2023-03-28 18:30:18 -07:00 committed by Denton Gentry
parent 71a5f2a989
commit 49e305f862
No known key found for this signature in database

View File

@ -1065,7 +1065,12 @@ func (ss *sshSession) run() {
var err error
rec, err = ss.startNewRecording()
if err != nil {
fmt.Fprintf(ss, "can't start new recording\r\n")
var uve userVisibleError
if errors.As(err, &uve) {
fmt.Fprintf(ss, "%s\r\n", uve)
} else {
fmt.Fprintf(ss, "can't start new recording\r\n")
}
ss.logf("startNewRecording: %v", err)
ss.Exit(1)
return
@ -1079,7 +1084,7 @@ func (ss *sshSession) run() {
logf("start failed: %v", err.Error())
if errors.Is(err, context.Canceled) {
err := context.Cause(ss.ctx)
uve := userVisibleError{}
var uve userVisibleError
if errors.As(err, &uve) {
fmt.Fprintf(ss, "%s\r\n", uve)
}
@ -1500,6 +1505,12 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) {
}
j = append(j, '\n')
if _, err := pw.Write(j); err != nil {
if errors.Is(err, io.ErrClosedPipe) && ss.ctx.Err() != nil {
// If we got an io.ErrClosedPipe, it's likely because
// the recording server closed the connection on us. Return
// the original context error instead.
return nil, context.Cause(ss.ctx)
}
return nil, err
}
return rec, nil