CVE-2026-102821: Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
A russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration.
The peer starts a key re-exchange (sends SSH_MSG_KEXINIT) but never sends the
follow-up SSH_MSG_KEX_ECDH_INIT, leaving the server’s kex state machine in
SessionKexState::InProgress indefinitely. While a rekey is in progress the
server’s three message-drain paths are all gated off (if !self.kex.active()),
but the network-read path stays active, so every SSH_MSG_CHANNEL_OPEN the peer
sends is processed inline and appends one reply to an unbounded internal
queue (priority_receiver, an UnboundedReceiver) that is not dequeued until
the rekey completes. Because the peer decides whether the rekey ever completes,
the queue — and the server’s memory — grows without bound.
This is reproducible end-to-end against a real russh server over a real encrypted transport; see “Proof of concept”. A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger.
References
Code Behaviors & Features
Detect and mitigate CVE-2026-102821 with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →