Skip to content

A wss dial that fails after the handshake frees its TLS state - #111

Merged
sepehr-safari merged 1 commit into
mainfrom
a-failed-upgrade-frees-its-tls-state
Sep 23, 2026
Merged

sepehr-safari merged 1 commit into
mainfrom
a-failed-upgrade-frees-its-tls-state

Conversation

@sepehr-safari

Copy link
Copy Markdown
Contributor

Closes #110.

The TLS state and its two 64 KiB buffers were freed only by errdefers inside the wss block that allocated them. Once that block had exited and transport.tls_state was set, a failure at the websocket upgrade, or a cancel while waiting for it, left all three behind. An errdefer at the level of the dial now frees them on any later failure. The success path is unchanged: Transport.deinit still owns them once the dial returns.

Verified

dial opens a real TLS connection, which CI cannot reach, so this was driven by hand under a leak-checking allocator against a local openssl s_server, with certificate checks disabled in a scratch build only:

Server Before After
answers the upgrade with a plain HTTP page (-www) HandshakeFailed, 3 leaks: the TlsState and both buffers HandshakeFailed, no leak
completes TLS and does not answer with 101 (-quiet) HandshakeFailed, the same 3 leaks HandshakeFailed, no leak

All 210 tests pass.

The TLS state and its two 64 KiB buffers were freed only by errdefers inside the block that allocated them. Once that block had exited, a failed websocket upgrade, or a dial cancelled while waiting for it, left all three behind. An errdefer at the level of the dial now frees them on every later failure.

Closes #110.
@sepehr-safari
sepehr-safari merged commit e0b1504 into main Sep 23, 2026
2 checks passed
@sepehr-safari
sepehr-safari deleted the a-failed-upgrade-frees-its-tls-state branch September 23, 2026 09:06
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.

A wss dial that fails after the TLS handshake leaks the TLS state

1 participant