Skip to content

smitebot: implement smitebot stop command#145

Open
Ashish-Kumar-Dash wants to merge 1 commit into
morehouse:masterfrom
Ashish-Kumar-Dash:stop-cmd
Open

smitebot: implement smitebot stop command#145
Ashish-Kumar-Dash wants to merge 1 commit into
morehouse:masterfrom
Ashish-Kumar-Dash:stop-cmd

Conversation

@Ashish-Kumar-Dash

@Ashish-Kumar-Dash Ashish-Kumar-Dash commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds smitebot stop <campaign-id>: tears down a running campaign and reaps all of its processes, including the Nyx QEMU children that a plain tmux kill-session leaks.

The problem

In Nyx mode each afl-fuzz runner spawns a QEMU child, and tmux kill-session only sends SIGHUP to the afl-fuzz panes, the QEMU children orphan (reparented away from tmux) and keep running.

How it works

Verified against the live process tree and AFL++ source:

  • Each afl-fuzz pane is its own process-group leader. Its QEMU child is in the same process group and keeps that group id even after it orphans. So one group-directed kill reaps the QEMU too.
  • In testing, an orphaned QEMU did not exit on SIGTERM, so the kill escalates SIGTERM → SIGKILL.
  • A killed afl-fuzz lingers as a zombie under tmux remain-on-exit until the session is torn down, so the "did everything die?" check ignores zombie (Z) states.

stop:

  1. Loads state.json for the campaign (errors name the path + how to list campaigns).
  2. Reads the live runner PIDs from the tmux session (tmux list-panes) — not from state.json, whose PIDs can be missing (slow startup) or stale/recycled (after a reboot), killing a recycled PID's group could hit an unrelated process.
  3. pkill -TERM -g <pgid> each group → waits (polling, non-zombie only) → pkill -KILL -g <pgid> any straggler.
  4. tmux kill-session to remove windows and reap the zombie leaders.
  5. Records status = "stopped" + stop_time in state.json.

state.json changes

  • New status stopped; new field stop_time: Option<u64> (#[serde(default)], so pre-existing state files still load).

Live end-to-end test I ran (2-runner lnd campaign):

Before — 2 afl-fuzz, their 2 QEMU, 1 session:

$ pgrep -a afl-fuzz ; pgrep -a qemu ; tmux ls
12122 .../afl-fuzz -Y ... -M 0 ...
12128 .../afl-fuzz -Y ... -S 1 ...
12131 .../qemu-system-x86_64 ... worker_id=0 ... load=off
12158 .../qemu-system-x86_64 ... worker_id=1 ... load=on
lnd-encrypted_bytes-1783687998: 2 windows

Stop, then re-check — zero survivors:

$ smitebot stop lnd-encrypted_bytes-1783687998
INFO  [smitebot::commands::stop] campaign lnd-encrypted_bytes-1783687998
stopped

$ pgrep -a afl-fuzz ; pgrep -a qemu ; tmux ls
no server running on /tmp/tmux-1000/default

$ grep -E 'status|stop_time'
~/.smitebot/runs/lnd-encrypted_bytes-1783687998/state.json
  "status": "stopped",
  "stop_time": 1783688225,

Ref. #70

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