1---2name: oss-fuzz3description: Use when enrolling a project in OSS-Fuzz, running its helper workflow locally, or reproducing an OSS-Fuzz report. Not for remote, credential, publish, deploy, or irreversible changes.4---56# OSS-Fuzz78## Contract910| Field | Bound contract |11|---|---|12| Trigger | User needs to enroll an open-source project in OSS-Fuzz, run its helper workflow locally, or reproduce an OSS-Fuzz report. |13| Authority | Reversible local: writes only named local artifacts (oss-fuzz clone, Docker images, project enrollment files); rollback is `docker rmi` for images and filesystem deletion for the clone. No remote mutation. |14| Side effect | OSS-Fuzz project integration files, Docker image builds, and local fuzzing campaign artifacts written to the oss-fuzz working directory. |15| Done | Task A: the project Docker image builds, fuzzers compile with AddressSanitizer, and the named harness executes. Task B: `projects/<project_name>/project.yaml`, `Dockerfile`, and `build.sh` are present and structurally valid. |1617## Inputs1819| Input | Required | Description |20|---|---|---|21| `project_name` | Required | OSS-Fuzz project identifier (slug used in `infra/helper.py` commands and the `projects/` subdirectory). |22| `harness_name` | Required for local run | Fuzzer executable name inside the project's build output directory. |23| `language` | Required for enrollment | Project language (e.g. `c++`, `python`, `rust`, `go`). |24| `main_repo` | Required for enrollment | URL of the project's primary source repository. |25| `sanitizer` | Optional | Sanitizer for `build_fuzzers`: `address` (default), `undefined`, `coverage`. |26| `fuzzer_args` | Optional | Extra arguments passed through to the fuzzer binary. |27| `oss_fuzz_dir` | Optional | Local path of the cloned oss-fuzz repository; defaults to `./oss-fuzz`. |28| `primary_contact` | Required for enrollment | Maintainer email for `project.yaml`. |2930## Procedure3132### Task A: run an enrolled project locally33341. Verify `docker` is available and the user has permission to run containers (`docker info` exits 0). Done when: `docker info` exits 0.352. Clone oss-fuzz if `oss_fuzz_dir` does not exist or is not a git repository:36 ```bash37 oss_fuzz_dir="${oss_fuzz_dir:-./oss-fuzz}"38 git clone https://github.com/google/oss-fuzz "$oss_fuzz_dir"39 ```40 Done when: the oss-fuzz repository is cloned and present at `oss_fuzz_dir`.413. Change to the oss-fuzz directory:42 ```bash43 oss_fuzz_dir="${oss_fuzz_dir:-./oss-fuzz}"44 cd "$oss_fuzz_dir"45 ```46 Done when: the working directory is the oss-fuzz directory.474. Build the project Docker image:48 ```bash49 project_name="${project_name:?project_name is required}"50 uv run --no-project python infra/helper.py build_image --pull "$project_name"51 ```52 If `build_image` reports the project directory does not exist under `projects/`, stop and return `enrollment-missing`. Done when: the project Docker image builds successfully or `enrollment-missing` is returned.535. Build the fuzzers with AddressSanitizer:54 ```bash55 project_name="${project_name:?project_name is required}"56 sanitizer="${sanitizer:-address}"57 uv run --no-project python infra/helper.py build_fuzzers --sanitizer="$sanitizer" "$project_name"58 ```59 Capture stdout/stderr. If the build exits non-zero, return `build-failed` with the captured output. Done when: fuzzers compile with the configured sanitizer and stdout/stderr are captured.606. Run the named harness:61 ```bash62 project_name="${project_name:?project_name is required}"63 harness_name="${harness_name:?harness_name is required}"64 fuzzer_args="${fuzzer_args:-}"65 uv run --no-project python infra/helper.py run_fuzzer "$project_name" "$harness_name" ${fuzzer_args:+"$fuzzer_args"}66 ```67 Observe for at least 10 seconds. If the harness exits with a sanitizer report, return `crash-detected` with the report path. Otherwise return `harness-ran`. Done when: the harness runs for at least 10 seconds and returns `harness-ran` or `crash-detected`.6869### Task B: enroll a new project70711. Verify the project has an OSS-Fuzz-compatible harness at `$main_repo` or an associated harness repository. Done when: a compatible harness is confirmed at `$main_repo` or the associated repository.722. Create `projects/<project_name>/` under the oss-fuzz directory. Done when: the project directory is created.733. Write `projects/<project_name>/project.yaml`:74 ```yaml75 homepage: "<main_repo>"76 language: "<language>"77 primary_contact: "<primary_contact>"78 main_repo: "<main_repo>"79 fuzzing_engines:80 - libfuzzer81 sanitizers:82 - address83 ```84 Extend `sanitizers` and `fuzzing_engines` if the task specifies additional values. Done when: `project.yaml` is written with all required fields and any extensions.854. Write `projects/<project_name>/Dockerfile` using `gcr.io/oss-fuzz-base/base-builder` as the base image; add language-specific and project-specific `RUN` commands to install build dependencies. Do not copy source code directly; use `git clone` in the Dockerfile. Done when: `Dockerfile` is written with the base image and `git clone` for source.865. Write `projects/<project_name>/build.sh` as an executable script:87 - Set `#!/bin/bash -eu`.88 - Clone or build project dependencies.89 - Compile harnesses using `$CXX`, `$CXXFLAGS`, `$LIB_FUZZING_ENGINE`, `$SRC`, and `$OUT` as provided by the OSS-Fuzz environment.90 - Copy corpus and dictionary files to `$OUT` if present.91 Done when: `build.sh` is written as an executable script with all four elements.926. Return `enrollment-artifacts-written` listing the three files and their paths. Done when: the three artifact paths are returned.9394## Failure and recovery9596| Failure class | Trigger | Result |97|---|---|---|98| `docker-unavailable` | `docker info` exits non-zero | Return `blocked: docker-unavailable`. Do not attempt container operations. |99| `enrollment-missing` | `projects/<project_name>` absent and task is local run | Return `blocked: enrollment-missing`. Enrollment is out of scope for local-run unless explicitly requested. |100| `build-failed` | `build_fuzzers` exits non-zero | Return `failed: build-failed` with captured stderr. Do not proceed to run step. |101| `crash-detected` | Harness exits with ASan/UBSan report | Return `crash-detected` with the report file path. Do not suppress or dismiss the report. |102| `rollback` | Any step fails; Docker images written by this session | Rollback: `docker rmi $(docker images --filter=reference="gcr.io/oss-fuzz/$(basename "$project_name")*" -q) 2>/dev/null`; delete the `oss_fuzz_dir` clone if this session created it. |103104## Output105106| Outcome | Output |107|---|---|108| Local run, build success, no crash | `done: harness-ran`: fuzzer is running and producing coverage or execution output. |109| Local run, crash detected | `crash-detected: <report-path>`: sanitizer report written to the build output directory. |110| Enrollment artifacts written | `done: enrollment-artifacts-written`: `project.yaml`, `Dockerfile`, `build.sh` paths listed. |111| Build failed | `failed: build-failed`: full build log for diagnosis. |112| Prerequisites not met | `blocked: <failure-class>`: reason stated, no progress claimed. |