77 lines
3 KiB
Bash
Executable file
77 lines
3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Run every fold detector against yams' release compile DB.
|
|
#
|
|
# Outputs per-detector SARIF + Markdown + stderr to $OUT.
|
|
# Usage:
|
|
# tools/audit-yams.sh [out-dir]
|
|
#
|
|
# Defaults match the audit plan; override OUT_DIR for clean runs.
|
|
|
|
set -uo pipefail
|
|
# Don't `-e`: a detector exiting 1 (findings emitted) is success here.
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
FOLD="${FOLD:-$HERE/../build/release/src/cli/fold}"
|
|
DB="${DB:-/Users/trevon/work/tools/yams/build/release/compile_commands.json}"
|
|
OUT="${1:-/tmp/yams-audit-2026-05-14}"
|
|
|
|
mkdir -p "$OUT"
|
|
|
|
run_one() {
|
|
local name="$1"
|
|
shift
|
|
local extra_args=("$@")
|
|
echo "=== $name ==="
|
|
local t0 t1
|
|
t0="$(date +%s)"
|
|
# SARIF + Markdown — fold needs two invocations because --format takes one value.
|
|
# --quarantine-dir lets fold record per-TU crashes (signal isolation) into
|
|
# $OUT/quarantine.txt and skip them on the second invocation.
|
|
"$FOLD" scan --compile-db "$DB" --detectors "$name" \
|
|
--quarantine-dir "$OUT" \
|
|
--format sarif --output "$OUT/$name.sarif" \
|
|
"${extra_args[@]}" 2> "$OUT/$name.stderr"
|
|
local rc_sarif=$?
|
|
"$FOLD" scan --compile-db "$DB" --detectors "$name" \
|
|
--quarantine-dir "$OUT" \
|
|
--format markdown --output "$OUT/$name.md" \
|
|
"${extra_args[@]}" 2>> "$OUT/$name.stderr"
|
|
local rc_md=$?
|
|
t1="$(date +%s)"
|
|
local count
|
|
count="$(grep -c '^### ' "$OUT/$name.md" 2>/dev/null || echo 0)"
|
|
printf " rc(sarif=%d md=%d) findings=%s elapsed=%ss\n" \
|
|
"$rc_sarif" "$rc_md" "$count" "$((t1 - t0))"
|
|
}
|
|
|
|
# Redundancy
|
|
run_one clone --min-body-stmts 8 --processes 1
|
|
run_one equiv --min-body-stmts 4 --processes 4 --budget-seconds 600 --per-query-ms 2000
|
|
# `dead` goes through the symbolic encoder and is vulnerable to a Clang
|
|
# `getTypeInfoImpl` infinite-recursion bug on one yams TU
|
|
# (storage_backend_factory.cpp). `--processes >=4` keeps the crash
|
|
# isolated to one worker shard so the audit completes.
|
|
run_one dead --min-body-stmts 4 --processes 4 --budget-seconds 900 --per-query-ms 2000
|
|
run_one class-dup --processes 1 --budget-seconds 600 --per-query-ms 2000
|
|
|
|
# CFG/call-graph (M16/M17 — non-symbolic, no Z3 budget needed)
|
|
run_one dead-statement --processes 1
|
|
run_one unused-function --processes 1
|
|
run_one static-ptr-asymmetry --processes 1
|
|
|
|
# Security (M7 + M18 interval pre-pass + M15 stdlib-sink hook).
|
|
# All four go through the symbolic encoder → use parallel mode so a
|
|
# single-TU Clang crash doesn't sink the detector.
|
|
run_one null-deref --processes 4
|
|
run_one div-by-zero --processes 4 --budget-seconds 600 --per-query-ms 2000
|
|
run_one int-overflow --processes 4 --budget-seconds 600 --per-query-ms 2000
|
|
run_one oob --processes 4 --budget-seconds 600 --per-query-ms 2000
|
|
|
|
echo
|
|
echo "=== summary ==="
|
|
for d in clone equiv dead class-dup dead-statement unused-function \
|
|
static-ptr-asymmetry null-deref div-by-zero int-overflow oob; do
|
|
count="$(grep -c '^### ' "$OUT/$d.md" 2>/dev/null || echo 0)"
|
|
printf " %-16s %s findings\n" "$d" "$count"
|
|
done
|
|
echo "outputs in: $OUT"
|