The vulnerability is a memory safety issue rooted in the russh-cryptovec crate and exposed through the russh crate's SSH agent handling. The core of the problem lies in unchecked memory allocation and buffer growth.
-
Unsafe Memory Handling in russh-cryptovec: The CryptoVec data structure, designed to handle sensitive data in memory, had several flaws. Its resize function and other methods that modified the vector's size (push, extend, etc.) used unchecked arithmetic. This could lead to integer overflows when calculating new buffer sizes, resulting in incorrect allocations. Furthermore, the underlying memory locking functions (mlock, munlock) on Unix-like systems unsafely assumed that the pointers they received were not null, using NonNull::new_unchecked, which could cause a process to crash if a zero-sized allocation resulted in a null pointer.
-
Unvalidated Input in russh: The russh crate used CryptoVec (or Vec in later versions, which still suffered from the allocation issue) to handle messages from SSH agents. The AgentClient::read_response (client-side) and Connection::run (server-side) functions would read a 4-byte length field from an agent, interpret it as a u32, and immediately resize a buffer to that length. There was no upper limit on this length. This allowed a malicious or compromised SSH agent to send a message with a very large length, triggering a massive memory allocation on the recipient's side, leading to a denial of service (DoS) due to memory exhaustion.
The patch addresses both layers of the problem. It hardens CryptoVec by replacing unchecked arithmetic with checked operations to prevent overflows and by validating pointers in mlock/munlock. It also mitigates the immediate DoS vector in russh by capping the acceptable agent frame length at 256 KB, rejecting any oversized frames before attempting to allocate memory for them.