Files
rustfs/fuzz
Hauser Zhi ed4099ebe1 chore(deps): update crates and fix storage CI regressions (#9111)
* chore(deps): refresh crates and adopt openidconnect 4.1

Use published OIDC/OAuth2 releases and reject malformed HMAC signature
lengths before upstream verification. Refresh workspace and fuzz locks,
and advance the local zstd compatibility patch to 0.13.4 while retaining
the fixed 0.14.3 codec backend.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* chore(deps): refresh compatible lockfile resolutions

Resolve Prost build and derive dependencies with itertools 0.14 and
prefer windows-sys 0.61.2 within the existing supported version ranges.
Retain all package versions, sources and checksums.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(connect): separate cleanup checks from short probe windows

Use the functional measurement budget for the cleanup HTTP fixture so
setup and measured I/O can finish before checking delete status handling.
Exercise both normal scheduling and an in-flight PUT clock advance, and
include target classification in unexpected-failure diagnostics.

Retain the cleanup deadline, outer timeout and delete-stage assertions.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(ecstore): isolate stalled multipart disk timeouts

Apply the short injected timeout only to the deliberately stalled disk.
Healthy disks retain their normal operation budgets, while logical lock,
physical owner, immediate CopyObject and final shard assertions remain.

Keep overrides scoped across cloned and reconnected handles, preserve
shorter caller deadlines and explicit zero timeouts, and report drive
health when the real CopyObject assertion fails.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(rebalance): retry metadata write lock quorum admission

Recognize typed write-lock quorum failures for rebalance.bin within the
existing bounded metadata admission retry policy. Each attempt must
acquire quorum before loading or saving metadata; data writes are not
replayed by this retry.

Cover recovered and persistent quorum failures, cancellation after a
failed attempt, and rejection of unrelated resource or read-lock errors.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-11-02 06:49:24 +00:00
..

RustFS Fuzz Harness

This directory contains the standalone cargo-fuzz harness for RustFS.

It is intentionally isolated from the main workspace so that:

  • root cargo fmt --all
  • root cargo nextest
  • root make pre-commit

continue to behave exactly as they do today.

Prerequisites

Install cargo-fuzz and a nightly toolchain locally:

cargo install cargo-fuzz
rustup toolchain install nightly

Layout

fuzz/
  Cargo.toml
  fuzz_targets/
  corpus/
  artifacts/

Crash reproducers are written under fuzz/artifacts/<target>/.

Targets

  • bucket_validation
    • Exercises RustFS bucket-name and bucket/object argument validation.
  • archive_extract
    • Exercises archive entry path normalization, prefix application, and bucket-namespace containment checks.
  • path_containment
    • Exercises object-path acceptance and containment invariants using public path helpers.
  • local_metadata
    • Exercises rustfs-filemeta metadata decoding and rustfs-utils block decompression.
  • policy_ingress
    • Exercises RustFS-owned bucket policy and policy-doc JSON ingress behavior, including strict-vs-tolerant unknown-field expectations.

Usage

Run a single target:

cd fuzz
cargo +nightly fuzz run path_containment

Use the unified runner script from the repository root:

# Build + run all smoke targets (60s each)
./scripts/fuzz/run.sh

# Build only (no fuzz run)
BUILD_ONLY=1 ./scripts/fuzz/run.sh

# Build + run a single target
FUZZ_TARGET=path_containment ./scripts/fuzz/run.sh

# Nightly-style: 300s per target
MAX_TOTAL_TIME=300 ./scripts/fuzz/run.sh

# Replay a recorded libFuzzer seed
FUZZ_TARGET=path_containment FUZZ_SEED=123456789 ./scripts/fuzz/run.sh

# Skip build (use pre-built harness)
SKIP_BUILD=1 FUZZ_TARGET=local_metadata ./scripts/fuzz/run.sh

Each run writes fuzz/artifacts/<target>/run-manifest.txt with the target, libFuzzer seed, time budget, Git revision and dirty state, and runner mode. CI uploads that manifest with the corpus and any crash input so the exact run can be replayed.

CI Workflow

The GitHub Actions workflow (.github/workflows/fuzz.yml) uses a build/run separation pattern:

  1. fuzz-build — compiles all fuzz targets once, then uploads only the prebuilt smoke harness binaries needed by later jobs.
  2. pr-fuzz-smoke — matrix job that runs each target in parallel (60s each). Downloads the prebuilt binaries and executes them directly, so the job does not need to restore the full fuzz/target/ tree or reinstall cargo-fuzz.
  3. nightly-fuzz-corpus — matrix job that reuses the same prebuilt binaries and runs each target in parallel (300s each) on a daily schedule.

This design avoids redundant compilation across targets and keeps wall-clock time low.

Seed Corpus

Initial seed directories live under fuzz/corpus/.

  • Keep small, representative, and target-specific inputs here.
  • Prefer checked-in fixtures for stable formats like xl.meta.
  • Use cargo fuzz cmin / cargo fuzz tmin to shrink corpora and crashes before committing them.

The helper scripts also invoke cargo +nightly fuzz ... explicitly so local execution does not depend on the default toolchain.