Skip to content

[bug] Bash tool on Windows: TOCTOU race in taskkill /T /F process tree cleanup (orphan leak) #33071

Closed as not planned

Description

Description

The Bash tool (packages/core/src/tool/bash.ts) creates child processes with detached: process.platform !== "win32" (L163). On Windows, detached is false, so no separate process group is created.

The kill path (packages/core/src/process/cross-spawn-spawner.ts) already has a killGroup function (L292-L312) that uses taskkill /pid ${proc.pid} /T /F on Windows to attempt tree-wide cleanup. However, a TOCTOU (time-of-check-time-of-use) race condition exists: when the shell command (e.g., cmd /c start /b ping -t localhost) spawns a child process, that child may become its own process group leader before taskkill /T enumerates the tree. The /T flag only kills processes that are direct descendants at the moment of execution. If a grandchild process is spawned during the window between shell start and timeout execution, it can escape cleanup.

Additionally, cmd /c combined with start /b creates sibling processes (not children of cmd.exe), which taskkill /T /F may miss because they exist outside the PID-rooted tree.

Steps to reproduce

  1. On Windows, ask the model to run: start /b ping -t localhost
  2. Wait for the Bash tool timeout (~30s default)
  3. The shell process is killed via taskkill /pid <cmd_pid> /T /F, but ping.exe may survive because it was created as a sibling rather than a child of cmd.exe
  4. Repeat — multiple orphan ping.exe processes accumulate in Task Manager

Expected behavior

Replace taskkill /T /F with Windows Job Objects (CreateJobObject/AssignProcessToJobObject) to guarantee tree-wide termination regardless of process group topology. Job objects cannot be escaped by child processes and survive across all race conditions.

Code location

Environment

OpenCode Desktop 1.17.8, Windows 11


About the duplicate flag: The referenced issues cover related Windows process-lifecycle bugs but with different focuses:

This issue specifically identifies a TOCTOU race in the taskkill /T /F approach and proposes Windows Job Objects as the fix, which is a distinct root cause and solution from the other issues.

Activity

  1. github-actions commented on Jun 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    These are related Windows/process-lifecycle issues and may overlap with or inform this report.

  2. Necmttn commented on Jun 21, 2026

    @Necmttn

    Windows process cleanup needs job-object or process-tree ownership, not only best-effort taskkill /T after timeout. Create the shell and descendants under an owned job when possible, track spawned child pids, and close/kill the job on timeout, abort, or session exit.

    At minimum, write a process cleanup receipt with root pid, known descendants, missed/escaped pids, timeout reason, and final kill result. That makes orphan leaks visible instead of leaving users to hunt high-CPU ping/cmd processes manually.


    Generated with ax.

  3. rekram1-node commented on Jun 22, 2026

    @rekram1-node
    Contributor

    STOP SPAMMING ISSUES.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions