Target Config Reference¶
Each target has one static configuration file:
Create or refresh it with:
bin/audit --target <target> also creates this file when it is
missing. Runtime values such as RESULTS_DIR and TARGET_REV are
written separately to .session-env.
Treat target.toml as generated config plus a small review
layer. The tooling infers:
- source metadata;
- build system;
- browser mode for known browser slugs;
- common ASan executables;
- common static libraries;
- default include paths;
- default sanitizer policy;
- default threat model controls.
Your job is to edit only values that remain unresolved or are wrong for this target.
The config is also part of triage:
attacker_controlsis read when deciding whether a crash trigger is a legitimate product input.- Reproduction export uses the repository URL, revision, build fields, and sanitizer paths to build a clean maintainer bundle.
A complete generic example¶
target = "libxml2"
upstream_url = "https://gitlab.gnome.org/GNOME/libxml2.git"
build_system = "cmake"
pinned_rev = "HEAD"
asan_bin = "build-asan/xmllint"
asan_lib = "build-asan/libxml2.a"
includes = ["include", "build-asan/include"]
link_libs = ["-lz", "-llzma", "-lm"]
is_browser = "0"
reachability_ignore = ["GNOME/libxml2"]
[threat_model]
attacker_controls = ["bytes"]
Generated fields to review¶
| Field | Meaning |
|---|---|
target |
Target slug. It should match targets/<target> and output/<target>. |
upstream_url |
Source repository URL used as metadata in exported bundles. |
build_system |
Informational build-system label such as cmake, meson, autotools, or mach. |
pinned_rev |
Revision recorded when the config was created. The live revision is captured at audit startup. |
asan_bin |
ASan executable used by generic or browser runs. Relative paths resolve under targets/<target>/. |
asan_lib |
ASan library used when compiling C harness testcases. |
includes |
Include directories for C harness builds. Relative paths resolve under targets/<target>/. |
link_libs |
Extra linker flags for C harness builds. |
is_browser |
"1" for browser mode, "0" for generic mode. |
One related field is not seeded: defines, compiler define flags
for C/C++ harness builds (such as -DFOO=1). Add it by hand when a
harness build needs it — or let the audit's automatic repair propose
it after repeated harness build failures (see
Configure a target).
Which fields you need depends on what the run will do:
- A generic CLI audit needs
asan_bin. - C harness testcases also need the selected sanitizer's library,
includes,defines, andlink_libs. - ASan uses top-level
asan_lib. UBSan / MSan / TSan harnesses use[sanitizer].ubsan_lib,msan_lib, ortsan_lib.
If only the executable path is correct, a CLI-first audit can still run. Leave the C harness fields unresolved until you actually need public API harnesses.
Header-only libraries¶
Some C++ libraries ship only headers — no static archive to link against.
- Leave
asan_libas the generatedFILL_MEcomment placeholder, or set it to an empty string. bin/export-reprowill emit areproduce.shthat compiles the harness directly against the target sources without a library link.includes,defines, andlink_libsstill apply normally.- If the harness later starts needing a real archive, replace
FILL_MEwith the path — the rest of the config does not change.
Optional fields¶
| Field | Meaning |
|---|---|
cmake_target |
CMake target name used when a generated bundle can rebuild a specific target. |
reachability_ignore |
Substrings removed from external caller search results, such as the project itself or vendored copies. |
target.toml is parsed as strict TOML. Invalid section headers
or malformed arrays fail fast instead of silently falling back to
top-level keys.
Sanitizers¶
The [sanitizer] section declares which sanitizer runners are
intentionally enabled for this target, and where to find each
sanitizer's optional suppression file.
Only ASan is enabled by default. The supported sanitizer slugs
are asan, ubsan, msan, tsan, and race; everything except
asan is opt-in per target. For when to enable each one and the
false-positive trade-offs, see
Configure a target.
Findings-only mode (no sanitizer)¶
For targets that have no sanitizer build — typical for
interpreted languages (Python, Ruby, PHP, …) or JVM runtimes
(Java, Kotlin) — set enabled to an explicit empty list:
With enabled = []:
bin/proberoutes testcases through[runner].bininstead of expecting an ASan binary.bin/run-asan genericskipsASAN_OPTIONSinjection so the language runtime sees a clean environment.- The triager auto-demotes runtime-diagnostic crashes (Python
tracebacks, Go panics, Ruby exceptions, Java stack traces, Node
fatal errors, Rust panics, …) from
crashes/tofindings/instead of rejecting them. Genuine sanitizer-class memory-safety signals (ASan, TSan, MSan, Go race detector) still stay incrashes/.
When [sanitizer] is absent entirely from target.toml, the
default — ["asan"] — kicks in. Only an explicit empty list opts the
target out.
Per-sanitizer keys¶
| Key | Meaning |
|---|---|
enabled |
List of sanitizer slugs intentionally enabled for this target. Defaults to ["asan"]. |
<name>_suppressions |
Path to a suppression file. Appended via <NAME>_OPTIONS=suppressions=… at runner startup. Missing files emit a warning but do not abort. |
<name>_options |
Additional colon-separated runtime options appended to <NAME>_OPTIONS. |
ubsan_bin / msan_bin / tsan_bin |
Per-sanitizer binary overrides for opt-in runners. asan_bin is the top-level ASan binary field. |
ubsan_lib / msan_lib / tsan_lib |
Optional per-sanitizer library used when compiling C/C++ HARNESS: testcases. ASan uses top-level asan_lib. |
Example¶
asan_bin = "build-asan/xmllint"
[sanitizer]
enabled = ["asan", "msan"]
asan_suppressions = "build-asan/asan-suppressions.txt"
msan_suppressions = "build-msan/msan-suppressions.txt"
msan_bin = "build-msan/xmllint"
msan_lib = "build-msan/libxml2.a"
UBSan and TSan follow the same shape — add the slug to enabled and
set the matching <name>_bin / <name>_lib / <name>_suppressions
keys.
Notes:
- Paths are relative to
targets/<target>/unless absolute. - Relative paths whose first segment is
build-asan,build-ubsan,build-msan, orbuild-tsanareAUDIT_BUILD_SUFFIX-aware. Insidebin/audit-container-shell, those paths resolve to the per-image suffixed build directory; outside the container the suffix is empty. - Unknown sanitizer slugs in
enabledare logged on stderr and dropped. The loader falls back to["asan"]if[sanitizer]was absent and nothing valid remains. - An explicit empty list (
enabled = []) is honoured as findings-only mode and is not re-defaulted to["asan"]. - Runner scripts warn when invoked for a sanitizer that is not
listed in
enabledbut do not abort. That keeps one-off reproduction and debugging commands usable.
Language runner¶
The [runner] section is the language-agnostic invocation
contract. It is used by bin/probe and bin/run-asan generic
whenever no sanitizer binary is configured. Most commonly when
[sanitizer] enabled = [], but also for compiled-language
targets that want to plug in a custom driver script.
| Key | Meaning |
|---|---|
bin |
Interpreter or driver program (python3, node, cargo, ruby, an absolute path to a wrapper script, …). |
args |
Literal argument list. {TESTCASE} is substituted with the testcase path; {TARGET_ROOT}, {RESULTS_DIR}, {TARGET_SLUG}, {SANITIZER}, and {SWIFT_SANITIZER} are also substituted at run time. |
env |
Extra KEY=VAL strings layered on the runtime environment (e.g. ["GORACE=halt_on_error=1"], ["PYTHONDEVMODE=1"]). The same runner tokens as args are substituted at run time. |
crash_patterns |
Additional regex strings the triager treats as crash signals beyond its built-in language-agnostic markers. Use sparingly. |
{TESTCASE} substitution rules:
- When
{TESTCASE}appears inargs, it is replaced in place and the runner does not also append the testcase path. - When
{TESTCASE}is absent, the runner adds the testcase path after the expanded args, in the conventional last position.
Examples¶
# Pure Python target — interpreter + dev-mode env.
[runner]
bin = "python3"
args = ["{TESTCASE}"]
env = [
"PYTHONDEVMODE=1",
"PYTHONPATH={TARGET_ROOT}:{TARGET_ROOT}/src:{TARGET_ROOT}/lib",
]
crash_patterns = []
# Go target — findings-only driver via `go run`.
[runner]
bin = "go"
args = ["run", "{TESTCASE}"]
env = ["GORACE=halt_on_error=1"]
crash_patterns = []
To enable the Go runtime race detector, set
[sanitizer] enabled = ["race"] and use
args = ["run", "-race", "{TESTCASE}"].
# Rust target — cargo run with stdin-fed testcase.
[runner]
bin = "cargo"
args = ["run", "--quiet", "--manifest-path", "{TARGET_ROOT}/Cargo.toml", "--", "{TESTCASE}"]
env = []
crash_patterns = []
# Swift package — runner compiles with the selected Swift sanitizer
# (`address`, `undefined`, or `thread`).
[runner]
bin = "swift"
args = ["run", "--quiet", "-c", "release", "-Xswiftc", "-sanitize={SWIFT_SANITIZER}", "-Xswiftc", "-O", "--package-path", "{TARGET_ROOT}", "{TARGET_SLUG}", "{TESTCASE}"]
env = []
crash_patterns = []
# Custom wrapper script — useful for Java/Kotlin builds that need
# a classpath or a wrapper that pre-configures JNI agents.
[runner]
bin = "./tools/run-testcase.sh"
args = ["{TESTCASE}"]
env = []
crash_patterns = ['^DEFENSIVE-ASSERT-FAILED:']
bin/setup-target emits a starter [runner] block driven by
the detected build system. The seeded values are commented when
the build system is unknown so the file is safe to parse before
the operator fills it in.
Threat model¶
attacker_controls describes what an external caller can
legitimately control. Triage compares crash report
Trigger source values against this list.
| Token | Meaning |
|---|---|
bytes |
Caller-controlled bytes: file, stream, packet, archive, media, regex, or similar data. |
call-sequence |
Ordered public API, script, plugin, or Web API calls. |
timing |
Event-loop scheduling, GC timing, JIT tier-up, or similar timing. |
race |
Thread or process interleaving. |
protocol-state |
Multi-message protocol state. |
env |
Process environment variables. |
fs-state |
Filesystem paths, presence, permissions, or layout. |
Unknown tokens are logged on stderr and ignored; if the resulting list
is empty, the loader defaults to ["bytes"]. The legacy spelling
call-order is accepted and normalised to call-sequence.
Examples:
Browser mode¶
Generic targets:
Browser or browser-like runtime targets:
Browser mode enables:
- browser and JS testcase assumptions;
- coverage-gated browser or shell runs when available;
- JS differential mode.
For browser targets, triage can also require plausible
web / content reachability before a crash stays in crashes/.
Shell-only or privileged-only crashes may still be useful
engineering evidence, but they should not be presented as
web-reachable security crashes without a real product path.
Firefox path conventions differ by platform. macOS builds normally use:
Linux builds normally use:
Coverage-ASan browser gating follows the same platform split,
checking XUL on macOS or libxul.so on Linux for
__sancov_guards.
Session environment¶
At audit startup, bin/audit writes the active session file:
It contains dynamic values:
RESULTS_DIR;TARGET_ROOT;TARGET_SLUG;TARGET_REV;LOGDIR;SESSION_STARTED.
bin/probe discovers the nearest .session-env by walking upward
from the testcase path and current directory. Scratch testcases under
results/ therefore do not need manual environment setup.
Strategy hints: [s4_diff_pairs] and [s6_peers]¶
bin/setup-target and bin/audit --new-target seed two optional
strategy-hint sections. Most operators leave them as generated — you
can also hand-edit or delete them, and the audit still runs.
[s4_diff_pairs] lists pairs of execution modes the harness can diff
for S4 (differential testing). Only browser/JS engine targets carry
meaningful defaults:
[s6_peers] lists upstream peer projects to mine for S6
(cross-project variant):
Empty or missing values are fine — both sections only suggest
additional strategy material. bin/audit --new-target can also
LLM-bootstrap a real [threat_model] and [s6_peers] instead of the
conservative defaults; you can re-run that derivation at any time:
bin/suggest-threat-model <slug> --apply --force-config # re-derive attacker_controls
bin/suggest-peers <slug> --apply --force-config # re-derive [s6_peers]
bin/setup-target accepts --no-llm-config to keep the deterministic
seed and skip LLM enrichment — not recommended unless you have a
specific reason to stay offline.
Generated versus live revision¶
pinned_rev in target.toml is metadata captured at setup
time. At audit startup, the live source revision is written to
.session-env as TARGET_REV.
Use the live revision in reports and exported bundles when the two differ. This lets you refresh a target without rewriting reviewed config on every source update.