Fake Pageant agent can crash russh SSH clients on Windows
A missing bounds check in the pageant crate lets any local Windows process feed russh an oversized length and read past an 8KB shared memory view.
By The Agentic Times ·

A vulnerability disclosed on 30 September 2026 in the pageant crate, part of the russh workspace, allows a malicious local process on Windows to crash SSH clients built on russh and, in some cases, read adjacent process memory. The flaw is tracked as CVE-2026-102820 in advisory GHSA-g4mp-vgx3-xrvm.
According to the advisory, the problem sits in MemoryMap::read in pageant/src/wmmessage.rs. The function copies a number of bytes chosen by the peer out of an 8192-byte shared-memory view without checking whether that number fits. The sibling function MemoryMap::write does carry a bounds check and returns an overflow error when an access is too large. The read path has never had one in any revision of the file, the advisory says, based on the file's commit history.
The byte count comes from a four-byte big-endian length prefix that the responding "Pageant" process writes into the shared mapping. The calling function, query_pageant_direct, creates the mapping at the agent's maximum message length of 8192 bytes, writes the request, sends a WM_COPYDATA window message, then reads back whatever length the peer supplied. Nothing verifies that four plus the stated size stays within 8192 bytes.
The advisory describes two deterministic outcomes. A large size makes the copy walk off the end of the view and fault on the next unmapped page, producing an access violation that crashes the russh SSH client. Separately, a size close to the maximum value of a 32-bit integer causes an allocation of roughly four gigabytes before any copy happens. A third, conditional outcome is information disclosure: if the memory immediately after the mapped view happens to be committed, read hands those adjacent bytes back to russh as the supposed agent response, which russh then parses as agent identities or signatures. The advisory calls that arm opportunistic because it depends on process memory layout.
The trust boundary is the crux of the issue. russh finds the agent by calling FindWindowW for a window with the class and title "Pageant", and passes the shared mapping's name inside the message structure. Any local process can register a window with that class and title, receive the mapping name, open the same mapping and write a hostile size. An unprivileged local process impersonating Pageant can therefore attack every russh-based SSH client that uses the Pageant agent, according to the advisory. The code path is reached from AgentClient::connect_pageant.
The issue is Windows-only, gated behind a cfg(windows) compilation flag, and requires a local attacker. It was verified against pageant version 0.2.2 as shipped in russh version 0.63.1, described in the advisory as the latest release at the time of writing.
The reporter says the bug was reproduced end to end against the real, unmodified crate rather than a model of it. The proof of concept is a Windows cross-build run under Wine inside a Linux container. It takes a path dependency on pageant and calls query_pageant_direct directly, while a second thread impersonates the agent. In the attack run, the fake agent declared a response length of 512 KiB against the 8192-byte view, and Wine reported an unhandled page fault at a page-aligned address with an exit code corresponding to an access violation. A control run with an in-bounds length of 16 bytes returned 20 bytes cleanly, isolating the missing bound as the only difference.
The incident record lists the status as reported.
Sources
- github.comhttps://github.com/advisories/GHSA-g4mp-vgx3-xrvm
