[BUG] Bash call defining a function that shadows a command it calls fork-bombs the host; fork-bomb detection misses it
What happened
A background subagent ran a Bash tool call that defined a shell function shadowing a standard command and then called that command inside the function's own body:
wc(){ sed -n "$2,$3p" specs/$1.md | wc -w | tr -d ' '; }; for r in ...; do set -- $r; echo "$1 $2-$3 $(wc $1 $2 $3)"; done
Inside the function, wc -w resolves to the function itself, so it recursed with no base case and forked a bash subshell and a tr at each level. Within about three seconds a single process chain held about 1,220 bash and 1,215 tr processes. Its root was a bash whose parent was the interactive Claude Code process, since subagents run inside the parent session's process. Process creation then failed for the whole user with fork: Resource temporarily unavailable (EAGAIN). It stayed that way for about two minutes, until the parent session stopped its subagents.
Impact
The limit is per user, so everything else on the host failed with it:
- other subagents' Bash calls failed;
- three unrelated background
claudesessions (in two different repositories) ended mid-task; - a concurrent test run went falsely red;
- the interactive shell could not run
echo.
Recovery took manual cleanup across both repositories.
Expected
Either:
- the Bash tool's fork-bomb detection (which exists, per #64309) also catches a function that shadows a command and calls that name in its own body without
command/builtin, and refuses the call before it runs; or - a runaway process tree under one tool call is bounded or killed (for example a per-call process cap, or the call's process group torn down once it passes a threshold), rather than exhausting the user's process limit for every session on the host.
Repro
In any session, ask for a Bash call like:
wc(){ cat "$1" | wc -w; }; wc /etc/hosts
Run it only where the process limit is safely low (for example under ulimit -u 200 in a throwaway shell).
Environment
- Claude Code 2.1.300
- macOS (Darwin 27),
kern.maxprocperuid4000 - The call came from a general-purpose background subagent dispatched by the Agent tool, in auto permission mode.