Skip to content

Don't crash on window adjust for a closed child channel#239

Open
andrewkomkov wants to merge 1 commit into
apple:mainfrom
andrewkomkov:window-adjust-closed-channel
Open

Don't crash on window adjust for a closed child channel#239
andrewkomkov wants to merge 1 commit into
apple:mainfrom
andrewkomkov:window-adjust-closed-channel

Conversation

@andrewkomkov

Copy link
Copy Markdown

Problem

ChildChannelStateMachine.sendChannelWindowAdjust calls preconditionFailure("Sent channel window adjust on channel in invalid state") for the closedLocally, closedRemotely, and closed states. Since preconditionFailure is fatal, hitting any of those states crashes the entire process.

This is reachable in normal operation. On a multiplexed session, a read can be delivered from the multiplexer's pending-read queue after the child channel has been closed locally (for example, the application cancels or closes a channel while reads are still in flight). Servicing that buffered read advances the inbound window and triggers an outbound window adjust, by which point the child channel state machine is already in a closed state, so the precondition fires and the whole process dies.

Stack summary

fatalError / preconditionFailure
  ChildChannelStateMachine.sendChannelWindowAdjust(...)   <- closedLocally / closedRemotely / closed
  SSHChildChannel (servicing a pending read after local close)
  SSHChannelMultiplexer (draining the pending-read queue)

Fix

sendChannelWindowAdjust already throws, so the closed states do not need to be fatal. For closedLocally, closedRemotely, and closed we now throw NIOSSHError.protocolViolation instead of calling preconditionFailure. The caller fails the associated promise and errors the channel, which is already closing, so the outcome is a clean, contained error rather than process death.

requestedLocally and requestedRemotely keep the existing preconditionFailure, since reaching those states here genuinely indicates an internal logic error.

Testing

  • swift build succeeds.
  • swift test passes (320 tests, 0 failures).

I understand the Swift project may require a CLA; happy to sign it.

A read delivered from the multiplexer's pending-read queue after local
channel close triggers an outbound window adjust on a closed channel.
The state machine used preconditionFailure, killing the whole process.
The function already throws; surface a protocol violation instead and
let the caller error the (already closing) channel.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant