SSHRequestHandler reaches SSHChannelPair over two paths that are not ordered against each other: onPtyRequest and onWindowChange run inline on the request-handler goroutine, while sessionSignals.started hands off to serve(), which only then creates the session recorder those callbacks read.
The handler replies to the session-start request before signaling started, so a client holding that reply can get a window-change back to the handler before serve() is scheduled. onWindowChange then reads a nil recorder and the resize is dropped from the recording. recMu makes the shared recorder safe to touch but does not order its creation before a callback that needs it.
Surfaced as a flaky TestChannelPair_SessionRecorderWriteErrors:
That test's resize coverage is parked behind TODO(#460) in internal/sshhandler/channel_pair_test.go. TestChannelPair_SessionShellRecording and TestChannelPair_RequestPanicClosesChannels send a window-change on the same path and can flake the same way, though neither has yet.
Desired outcome:
- One ordered path between the request handler and the channel pair, so an event that follows the session start is applied after the recorder exists.
- A single owner of the recorder, retiring the shared variable and
recMu.
- Restore the parked resize coverage.
SSHRequestHandlerreachesSSHChannelPairover two paths that are not ordered against each other:onPtyRequestandonWindowChangerun inline on the request-handler goroutine, whilesessionSignals.startedhands off toserve(), which only then creates the session recorder those callbacks read.The handler replies to the session-start request before signaling
started, so a client holding that reply can get awindow-changeback to the handler beforeserve()is scheduled.onWindowChangethen reads a nil recorder and the resize is dropped from the recording.recMumakes the shared recorder safe to touch but does not order its creation before a callback that needs it.Surfaced as a flaky
TestChannelPair_SessionRecorderWriteErrors:That test's resize coverage is parked behind
TODO(#460)ininternal/sshhandler/channel_pair_test.go.TestChannelPair_SessionShellRecordingandTestChannelPair_RequestPanicClosesChannelssend awindow-changeon the same path and can flake the same way, though neither has yet.Desired outcome:
recMu.