Skip to content

Nyovelt/fuzz-coreutils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fuzz-coreutils

Coverage-guided differential fuzzing for GNU coreutils versus uutils/coreutils powered by libAFL. The harness repeatedly feeds the same stdin into both implementations and preserves any behavioural differences for later triage.

Repository Layout

  • scripts/run_libafl.sh — convenience wrapper that invokes the Rust harness with cargo run.
  • fuzzers/libafl-diff/ — libAFL-based differential fuzzer; run it directly or via the script.
  • instrumented-coreutils/ — checkout of the uutils project that you build with coverage instrumentation (ignored by git so you can clone your own copy).
  • queue-* — per-target libAFL queues keeping the evolving corpus.
  • artifacts-* — saved repro bundles for divergences (stdin, stdout/stderr pairs, metadata).
  • reports/ — human-readable write-ups once a divergence is confirmed (see the uu-nl example).
  • logs/ — optional run logs (ignored by VCS).

Prerequisites

  1. Rust toolchain (stable ≥ 1.70 is fine; nightly also works).
  2. clang + lld so the AFL runtime links cleanly (apt install clang lld on Debian/Ubuntu).
  3. cargo-afl (cargo install cargo-afl) or another compiler wrapper that emits LLVM coverage instrumentation.
  4. A GNU coreutils installation (e.g. /usr/bin) to act as the reference implementation.

Prepare instrumented uutils binaries

Clone uutils and build the utilities you want to fuzz with AFL instrumentation enabled:

git clone https://github.com/uutils/coreutils instrumented-coreutils

env RUSTFLAGS='-C linker=clang -C link-arg=-fuse-ld=lld \
              -C link-arg=-Wl,--no-as-needed -C link-arg=-ldl' \
    PROG_PREFIX=uu- \
    cargo afl build --release \
    --manifest-path instrumented-coreutils/Cargo.toml \
    -p uu_nl

The resulting binary lives at instrumented-coreutils/target/release/uu-nl. Repeat the final cargo afl build invocation with a different package (-p uu_sort, -p uu_base64, …) for each extra utility you want to cover.

Run the harness

Point the harness at matching GNU and uutils binaries and let libAFL drive the inputs:

./scripts/run_libafl.sh \
  --util nl \
  --uutils-path "$(pwd)/instrumented-coreutils/target/release" \
  --gnu-path /usr/bin \
  --queue queue-libafl-nl \
  --artifacts artifacts-libafl-nl \
  --timeout-sec 3 \
  --max-iterations 0

Key options (run ./scripts/run_libafl.sh --help for the full list):

  • --util — utility name without the uu- prefix; defaults to cat.
  • --uutils-path / --gnu-path — directories that contain the instrumented uutils binaries and the reference GNU binaries respectively.
  • --queue / --artifacts — output directories; you can run multiple fuzzers in parallel by giving each its own pair.
  • --arg — repeatable flag to pin baseline arguments that should be present on every execution (e.g. --arg --number).
  • --timeout-sec and --max-iterations — per-execution timeout and an optional iteration cap (set to 0 for “run forever”).

Tips:

  • Pin runs to dedicated cores when you fan out multiple harnesses, e.g. taskset -c 80-95 ./scripts/run_libafl.sh ….
  • Seed queue-* with interesting inputs before launching to bias exploration; the harness will create the directory if it doesn’t exist.
  • Keep an eye on logs/ (if you redirect output there) to see throughput, unique crashes, and other libAFL stats.

Investigate findings

  • queue-* contains the evolving corpus of interesting inputs that survive minimisation.
  • artifacts-*/<util>/case-*/ holds reproducer bundles with stdin, stdout/stderr for both binaries, exit code summaries, and metadata (including a stable hash you can reference in reports).
  • Once you confirm a behavioural gap, drop a Markdown write-up under reports/ mirroring the format in reports/uu-nl-multiple-b-flags.md.

Docker usage (optional)

The provided Dockerfile installs Rust, clang, and related tooling on top of Ubuntu 24.04. Build it if you want an isolated environment:

docker build -t fuzz-coreutils .
docker run --rm -it -v "$PWD":/work fuzz-coreutils

Inside the container you still need to clone uutils and build your instrumented binaries as shown above.

Housekeeping

  • Heavy fuzzing runs produce a lot of bundles—prune artifacts-* and queue-* periodically to keep disk usage in check.
  • Keep the uutils checkout fresh (git pull) to fuzz new releases.
  • When filing upstream issues, include the metadata and repro files from the relevant artifacts-* directory so maintainers can verify the discrepancy.

Happy hunting!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors