Add a Target¶
Adding a target means giving the harness three things:
- source code under
targets/<target>/; - sanitizer artifacts built from that source (C/C++ only);
- a
output/<target>/target.tomlthat describes how to run and triage the target.
Once those are in place, TokenFuzz can build a ranked work queue,
launch agents, and write all audit evidence under
output/<target>/<backend>/results/.
What makes a good first target¶
Pick something with:
- a source checkout you are authorised to audit;
- a reproducible default ASan build;
- a command-line binary or public C API the harness can drive;
- existing tests, samples, or corpus files that agents can mutate;
- a clear external input boundary — bytes, protocol state, script calls, filesystem state;
- enough source structure for the ranker to find real implementation files (not just tests, generated code, or build glue).
Get one target clean and finishing healthy runs before adding more.
1. Sync the source¶
Create or update the checkout and seed the config:
A few real examples:
bin/setup-target libxml2 https://gitlab.gnome.org/GNOME/libxml2.git
bin/setup-target zlib https://github.com/madler/zlib.git
bin/setup-target firefox https://hg.mozilla.org/mozilla-unified --repo-type hg
Three useful variants:
bin/setup-target <target> # re-inspect existing checkout
bin/setup-target <target> <repo-url> --ref <branch-or-rev> # clone + pin to a revision
bin/setup-target <target> --ref <branch-or-rev> # switch the existing checkout
Notes:
- If a checkout already exists under
targets/<target>/, the no-URL form normally seeds or refreshes the generated config without touching source. It can still force the Python bootstrap when it detects stale ABI-tagged extension modules. - Re-running
setup-targetrefreshes generated config fields from the current checkout and build outputs. (--no-llm-configskips the LLM-backed threat-model and peer suggestions if you must stay offline.) - The full list of advanced flags is in Commands. The normal setup flow does not need them.
2. Bootstrap the build¶
Run once per target:
--bootstrap does whatever the detected build_system needs:
- C/C++ (
cmake/autotools/meson) —bin/auto-build-scriptiterates on a vanilla ASan recipe until it produces a working build, then writes the validated script totargets/<target>/.audit/build.sh.bin/export-reproinlines that script verbatim into everyreproduce.sh, so maintainers get the same build the audit used. - Python / Node / PHP / Ruby / Rust / Go / Swift — runs the
language's native install step (
setup.py build_ext --inplace,npm install,composer install,bundle install,cargo build,go build ./...,swift build). Required when the runner willimport(orrequire, …) something the source tree builds or downloads. - Anything else (Java, Kotlin, Perl, R, Shell, …) — no-op.
Skips silently when its inputs aren't present (no LLM backend, no manifest, no recognised build system, recipe already exists). Safe to pass on any target.
UBSan, MSan, and TSan are optional add-ons enabled later through
target.toml's [sanitizer] block.
When you do not need --bootstrap¶
Pure-Python / pure-Ruby / pure-JS scripts with no native extensions or
vendored dependencies, and non-C/C++ targets where you are happy to
run testcases through the language's own interpreter without a
sanitizer build. bin/setup-target writes a runner-only config
([sanitizer] enabled = []) for those — diagnostics land under
findings/ instead of crashes/. See
Auditing non-C/C++ targets for the
per-language matrix.
Inside bin/audit-container-shell¶
The container helper sets AUDIT_BUILD_SUFFIX so build directories
are isolated per image (build-asan-<image-id>/). Harness path
resolution applies it to relative build-asan/, build-ubsan/,
build-msan/, and build-tsan/ paths automatically; outside the
container the suffix is empty.
Writing the build recipe by hand¶
auto-build-script is the supported path. If you need to override —
no LLM backend available, exotic build system, in-tree patches — drop
a shell script with the contract argv = <src> <build> at
targets/<target>/.audit/build.sh and bin/export-repro will inline
it the same way.
3. Refresh and review the generated config¶
With the ASan build in place, ask the harness to look again:
This re-inspects build-asan${AUDIT_BUILD_SUFFIX:-}/ and updates
output/<target>/target.toml when generated placeholders remain.
Then open the file and edit only:
- placeholder values such as
FILL_ME; - artifact paths the generator guessed incorrectly;
- target-specific
defines; - target-specific
link_libs; attacker_controls, when the default input boundary is too narrow or too broad. Valid tokens arebytes,call-sequence,timing,race,env,protocol-state, andfs-state(seelib/target_config.sh/lib/target_config.py).
For the review checklist, see Configure a target. For complete field definitions, see Target config reference.
Where the agent guide lives¶
When bin/audit launches an agent, it injects the long-form guide
AGENTS.md into the prompt. The same guide covers browser and generic
targets — it describes the testcase format, strategy priority, and
crash quality bar that the agent is expected to follow. If you want to
tune agent behaviour for your target, that file is the right place to
look first — it is read at audit start and embedded into every agent
prompt.
4. Validate before long runs¶
Run one iteration:
Both bin/setup-target and bin/audit validate target.toml
themselves. If startup succeeds, you should see:
output/<target>/<backend>/results/.session-env
output/<target>/<backend>/results/
output/<target>/<backend>/logs/
Also check that the first run produced work-cards.jsonl and
state/. Those two files show whether the target is schedulable, even
when the bounded run did not make it as far as a crash.
5. Keep it updated¶
To refresh source while preserving configuration:
If ASan paths change after an upstream update, run
bin/setup-target <target> again after rebuilding, then review only
the affected artifact fields. Reviewed config is preserved unless
generated placeholders remain.
Ready checklist¶
A target is ready when:
targets/<target>/is a Git or Mercurial checkout;- the default ASan artifacts exist and start cleanly outside the harness;
output/<target>/target.tomlexists.bin/audit --target <target>creates it if it is missing.bin/setup-targetcan refresh it from source;- the fields you actually need have no placeholder values;
asan_binis correct for CLI or browser runs;asan_lib,includes,defines, andlink_libsare correct if ASan C harnesses will be used. UBSan / MSan / TSan harnesses use their own optional[sanitizer].*_libentries;is_browsermatches the target's execution model;attacker_controlsmatches the real external input boundary;bin/audit --target <target> --backend <backend> 1finishes startup and writes state underoutput/<target>/<backend>/results/;work-cards.jsonlexists and points at implementation files worth auditing;findings/andcrashes/both exist — either may be empty after a smoke run.