Skip to content

fix(windows): update mio to 1.2.4, a crash in the relay pipe under many connections - #911

Open
afpruivo wants to merge 1 commit into
Louis-CFM:mainfrom
afpruivo:fix/windows-mio-named-pipe-crash
Open

afpruivo wants to merge 1 commit into
Louis-CFM:mainfrom
afpruivo:fix/windows-mio-named-pipe-crash

Conversation

@afpruivo

Copy link
Copy Markdown
Contributor

Coucou for Windows can crash with heap corruption (0xC0000374, no panic, no log line: the process just disappears) when many hook connections open and close quickly on the relay pipe. The cause is in mio 1.2.3, the library under tokio's named pipes: a use-after-free reported as tokio-rs/mio#2011 and fixed by tokio-rs/mio#2014 in mio 1.2.4.

This PR only bumps mio 1.2.3 → 1.2.4 in windows/Cargo.lock (two lines; nothing else in the lockfile changes, cargo test --locked accepts it).

How I found it. While testing #872 (#853, hook server stops after a failed connect), I hammered the pipe: 8 workers opening and closing client connections for 10 s (script below). Coucou didn't hang; it crashed. Windows' crash log shows coucou.exe with c0000374 each time.

Verification on Windows 11 Pro 26H2 (20-thread CPU):

Build mio Result
Installed 0.5.2 1.2.3 crashed
#872 branch 1.2.3 crashed 3/3
Minimal tokio-only copy of pipe.rs's loop (no Coucou code) 1.2.3 crashed 6/6
Same minimal copy 1.2.4 survived 6/6
This branch 1.2.4 survived 3/3, real Claude Code hooks still arrive afterwards

The minimal copy crashes even when each connection is dropped right away without reading, so it's not Coucou's handler code.

cargo test --lib: 516 passed. npm test: 466 passed.

Does it happen in normal use? I haven't seen it happen on its own: a normal session sends far fewer connections than this test. The mio issue says it needs a busy multi-threaded runtime, which a burst of parallel subagents or a loaded machine can produce. So it's a rare crash, but an easy fix.

About #872: in these runs, the failed-connect() path it fixes never ran, so this doesn't replace it. It just fixes a different way the relay pipe can die.

Stress script (PowerShell)
$name = "coucou-" + [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
$jobs = 1..8 | ForEach-Object { Start-Job -ArgumentList $name { param($name)
  $end = (Get-Date).AddSeconds(10)
  while ((Get-Date) -lt $end) {
    $c = New-Object System.IO.Pipes.NamedPipeClientStream(".", $name, [System.IO.Pipes.PipeDirection]::InOut)
    try { $c.Connect(50) } catch {} finally { $c.Dispose() }
  } } }
$jobs | Wait-Job | Out-Null
Get-Process coucou   # gone on mio 1.2.3

🤖 Generated with Claude Code

…ny connections

mio 1.2.3 has a use-after-free in Windows named pipes (tokio-rs/mio#2011,
fixed by tokio-rs/mio#2014): many hook connections opening and closing
quickly crash Coucou with STATUS_HEAP_CORRUPTION (0xC0000374).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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