# Technical Documentation: google/oss-fuzz

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/google/oss-fuzz)

### Overview (`README.md`)

# OSS-Fuzz: Continuous Fuzzing for Open Source Software

[Fuzz testing] is a well-known technique for uncovering programming errors in
software. Many of these detectable errors, like [buffer overflow], can have
serious security implications. Google has found [thousands] of security
vulnerabilities and stability bugs by deploying [guided in-process fuzzing of
Chrome components], and we now want to share that service with the open source
community.

[Fuzz testing]: https://en.wikipedia.org/wiki/Fuzz_testing
[buffer overflow]: https://en.wikipedia.org/wiki/Buffer_overflow
[thousands]: https://issues.chromium.org/issues?q=label:Stability-LibFuzzer%20-status:Duplicate,WontFix
[guided in-process fuzzing of Chrome components]: https://security.googleblog.com/2016/08/guided-in-process-fuzzing-of-chrome.html

In cooperation with the [Core Infrastructure Initiative] and the [OpenSSF],
OSS-Fuzz aims to make common open source software more secure and stable by
combining modern fuzzing techniques with scalable, distributed execution.
Projects that do not qualify for OSS-Fuzz (e.g. closed source) can run their own
instances of [ClusterFuzz] or [ClusterFuzzLite].

[Core Infrastructure Initiative]: https://www.coreinfrastructure.org/
[OpenSSF]: https://www.openssf.org/

We support the [libFuzzer], [AFL++], and [Honggfuzz] fuzzing engines in
combination with [Sanitizers], as well as [ClusterFuzz], a distributed fuzzer
execution environment and reporting tool.

[libFuzzer]: https://llvm.org/docs/LibFuzzer.html
[AFL++]: https://github.com/AFLplusplus/AFLplusplus
[Honggfuzz]: https://github.com/google/honggfuzz
[Sanitizers]: https://github.com/google/sanitizers
[ClusterFuzz]: https://github.com/google/clusterfuzz
[ClusterFuzzLite]: https://google.github.io/clusterfuzzlite/

Currently, OSS-Fuzz supports C/C++, Rust, Go, Python, Java/JVM, JavaScript and Lua code. Other languages
supported by [LLVM] may work too. OSS-Fuzz supports fuzzing x86_64 and i386
builds.

[LLVM]: https://llvm.org

## Overview


## Documentation
Read our [detailed documentation] to learn how to use OSS-Fuzz.

[detailed documentation]: https://google.github.io/oss-fuzz

## Trophies
As of May 2025, OSS-Fuzz has helped identify and fix over 13,000 vulnerabilities and 50,000 bugs across [1,000] projects.

[1,000]: https://github.com/google/oss-fuzz/tree/master/projects

## Blog posts
* 2024-11-20 - [Leveling Up Fuzzing: Finding more vulnerabilities with AI]
* 2023-08-16 - [AI-Powered Fuzzing: Breaking the Bug Hunting Barrier]
* 2023-02-01 - [Taking the next step: OSS-Fuzz in 2023]
* 2022-09-08 - [Fuzzing beyond memory corruption: Finding broader classes of vulnerabilities automatically]
* 2021-12-16 - [Improving OSS-Fuzz and Jazzer to catch Log4Shell]
* 2021-03-10 - [Fuzzing Java in OSS-Fuzz]
* 2020-12-07 - [Improving open source security during the Google summer internship program]
* 2020-10-09 - [Fuzzing internships for Open Source Software]
* 2018-11-06 - [A New Chapter for OSS-Fuzz]
* 2017-05-08 - [OSS-Fuzz: Five months later, and rewarding projects]
* 2016-12-01 - [Announcing OSS-Fuzz: Continuous fuzzing for open source software]

[Leveling Up Fuzzing: Finding more vulnerabilities with AI]: https://security.googleblog.com/2024/11/leveling-up-fuzzing-finding-more.html
[AI-Powered Fuzzing: Breaking the Bug Hunting Barrier]: https://security.googleblog.com/2023/08/ai-powered-fuzzing-breaking-bug-hunting.html
[Announcing OSS-Fuzz: Continuous fuzzing for open source software]: https://opensource.googleblog.com/2016/12/announcing-oss-fuzz-continuous-fuzzing.html
[OSS-Fuzz: Five months later, and rewarding projects]: https://opensource.googleblog.com/2017/05/oss-fuzz-five-months-later-and.html
[A New Chapter for OSS-Fuzz]: https://security.googleblog.com/2018/11/a-new-chapter-for-oss-fuzz.html
[Fuzzing internships for Open Source Software]: https://security.googleblog.com/2020/10/fuzzing-internships-for-open-source.html
[Improving open source security during the Google summer internship program]: https://security.googleblog.com/2020/12/improving-open-source-security-during.html
[Fuzzing Java in OSS-Fuzz]: https://security.googleblog.com/2021/03/fuzzing-java-in-oss-fuzz.html
[Improving OSS-Fuzz and Jazzer to catch Log4Shell]: https://security.googleblog.com/2021/12/improving-oss-fuzz-and-jazzer-to-catch.html
[Fuzzing beyond memory corruption: Finding broader classes of vulnerabilities automatically]: https://security.googleblog.com/2022/09/fuzzing-beyond-memory-corruption.html
[Taking the next step: OSS-Fuzz in 2023]: https://security.googleblog.com/2023/02/taking-next-step-oss-fuzz-in-2023.html

---

### Overview (`docs/README.md`)

# Readme

Use the following instructions to make documentation changes locally.

## Prerequisites
```bash
$ sudo apt install ruby bundler
$ bundle config set path 'vendor/bundle'
$ bundle install
```

## Serving locally
```bash
$ bundle exec jekyll serve
```

## Theme documentation
We are using the [just the docs](https://just-the-docs.github.io/just-the-docs/)
theme.

---

### Overview (`infra/README.md`)

# infra
> OSS-Fuzz project infrastructure

Core infrastructure:
* [`base-images`](base-images/) - docker images for building fuzz targets & corresponding jenkins
  pipeline.

Continuous Integration infrastructure:

* [`ci`](ci/) - script to build projects in CI.

## helper.py
> script to automate common docker operations

| Command | Description |
|---------|-------------
| `generate`      | Generates skeleton files for a new project |
| `build_image`   | Builds a docker image for a given project |
| `build_fuzzers` | Builds fuzz targets for a given project |
| `run_fuzzer`    | Runs a fuzz target in a docker container |
| `coverage`      | Runs fuzz target(s) in a docker container and generates a code coverage report. See [Code Coverage doc](https://google.github.io/oss-fuzz/advanced-topics/code-coverage/) |
| `reproduce`     | Runs a testcase to reproduce a crash |
| `shell`         | Starts a shell inside the docker image for a project |

---

### Overview (`infra/base-images/README.md`)

# Base Images

This directory contains the base images used by OSS-Fuzz.

## Building

To build all images, run:

```bash
# run from project root
infra/base-images/all.sh
```

## Trial Builds for Testing Changes

When making changes to any of the base images, it's crucial to test them using the trial build system. This system is designed to build test versions of the images, identified by a `-testing` suffix, and use them to build a subset of OSS-Fuzz projects to ensure the changes don't cause regressions.

### Architecture Overview

The trial build system now supports building multiple Ubuntu base variants in parallel to accelerate testing. The supported variants are:
- `latest` (based on the default `Dockerfile`)
- `ubuntu-20-04` (based on `ubuntu-20-04.Dockerfile`)
- `ubuntu-24-04` (based on `ubuntu-24-04.Dockerfile`)

When a trial build is triggered on a Pull Request that modifies files in `infra/base-images/`, the system initiates three separate, parallel builds in Google Cloud Build (GCB). Each of these builds is responsible for building all base images for a single Ubuntu variant. This parallel architecture allows for faster feedback on changes across different base OS versions.

### How to Trigger a Trial Build

1.  Create a Pull Request with your changes to the base images.
2.  Once the PR is open, add a comment with the following command:
    ```
    /gcbrun trial_build.py all
    ```
3.  This command will be picked up by our CI system. It will first trigger a "coordinator" build, which then spawns the three parallel builds for the different Ubuntu variants. You can monitor the progress of these builds directly in the Google Cloud Build interface linked in your PR.

## Dependency Tree

The following diagram shows the dependency tree of the base images.

```mermaid
graph TD
    A[base-image] --> B(base-clang);
    B --> C(base-builder);
    C --> D(base-builder-go);
    C --> E(base-builder-javascript);
    C --> F(base-builder-jvm);
    C --> G(base-builder-python);
    C --> H(base-builder-ruby);
    C --> I(base-builder-rust);
    C --> J(base-builder-swift);
    C --> K(base-builder-fuzzbench);
    A --> L(base-runner);
    B --> L;
    C --> L;
    H --> L;
    L --> M(base-runner-debug);
```

---

### Overview (`infra/chronos/README.md`)

# Chronos: rebuilding OSS-Fuzz harnesses using cached builds

Chronos is a utility tooling to enable fast re-building of OSS-Fuzz projects
and analysis of projects' testing infrastructure. This is used by projects,
e.g. [OSS-Fuzz-gen](https://github.com/google/oss-fuzz-gen) to help speed up
valuation processes during fuzzing harness generation.

At the core, Chronos relies on caching containers after project build, in order
to enable fast rebuilding of a project following minor patches, and also enable
running of the tests in a given project. To support this, Chronos creates a snapshot
of the Docker container given project post build completion. This means that all `.o` files, generated
configurations etc. persist in the Docker container. These artifacts are then
leveraged for future "replay builds" where only a minor part of the project has changed,
e.g. due to some patching on the project. This patching could be e.g. minor adjustments
to the fuzzing harness source code e.g. by [oss-fuzz-gen](https://github.com/google/oss-fuzz-gen).

As such, at the core of Chronos are cached containers that are generated by taking a
snapshot of the container of a project post project build.

Chronos is focused on two features, rebuilding projects fast and running the
tests of a given project.


## Chronos features: fast rebuilding and running the tests of a project

### CLI interface for Chronos

The default route to validating Chronos is using the CLI available in `infra/experimental/chronos/manager.py`

### Chronos feature: Fast rebuilding

Chronos enables rebuilding projects efficiently in contexts where only a small patch
needs to be evaluated in the target. This is achieved by running a replay build script
in the build container, similarly to how a regular `build_fuzzers` command would run, but
with the caveat that the replay build script only performs a subset of the operations
of the original `build.sh`.

The replay build scripts are constructed in two ways: manually or automatically.

#### Option 1: Automated rebuilds

Chronos supports automated rebuilding. This is meant as a generic mechanism to enable Chronos support for projects by default. This is achieved by:

1. Calling into a `replay_build.sh` script during the building inside the container [here](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/infra/base-images/base-builder/compile#L292-L296)
2. The `replay_build.sh` calls into `make_build_replayable.py`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/replay_build.sh)
3. `make_build_replayable.py` adjusts the build environment to wrap around common commands, to avoid performing a complete run of `build.sh`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/make_build_replayable.py).

The automated rebuilding works in combination with [Ccache](https://ccache.dev/), in order to facilitate caching of e.g. `.o` files.
This means that during rebuild mode as long as we have a cache, we don't need to e.g. run `configure` again and will only have to
rebuild the changed source code.

#### Option 2: Manually provided replay builds

`replay_build.sh` above, is simply just a wrapper script around `build.sh` that aims to enable
fast rebuilding of the project. This `replay_build.sh` can, however, be overwritten in the Dockerfile
of the project's builder image to support a custom approach to fast rebuilding. Two examples of this is [php](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/projects/php/replay_build.sh#L1) and [ffmpeg](https://github.com/google/oss-fuzz/blob/master/projects/ffmpeg/replay_build.sh#L1).

Providing a manual `replay_build.sh` is likely more efficient at build time and can help speed up the process. Automated replay build scripts can also be erroneous.


#### Testing the validity of a replay build

The Chronos manager can use the `manager.py` to validate the validity of a
replay build for a given project:

```sh
python3 infra/experimental/chronos/manager.py check-replay tinyobjloader
```

If the above command fails for the relevant project, then the replay build feature
does not work for the given project.

### Chronos feature:  Running tests of a project

The second part of Chronos is a feature to enable running the tests of a given
project. This is done by way of a script `run_tests.sh`. Samples of
this script include [jsonnet](https://github.com/google/oss-fuzz/blob/master/projects/jsonnet/run_tests.sh#L1) and [tinyobjloader](https://github.com/google/oss-fuzz/blob/master/projects/tinyobjloader/run_tests.sh#L1).


#### Run tests constraints

1. The `run_tests.sh` main task is to run the tests of a project and return `0` upon success and non-null otherwise.
2. The `run_tests.sh` script must leave the main repository in the state as it was prior to the execution of `run_tests.sh` relative to `git diff` (or similar diff features of other version control systems).

#### Testing the validity of run_tests.sh

The Chronos manager can use the `manager.py` to validate the validity of a
`run_tests.sh` script:

```sh
python3 infra/experimental/chronos/manager.py check-tests json-c
```


### Constraints imposed on replay_build.sh and run_tests.sh

At the core of chronos are the two scripts `replay_build.sh` and `run_tests.sh`. We have a default
mechanism for `replay_build.sh` so it's not strictly necessary to have a custom one, although it will
likely improve speed and maybe correctness by providing one.

There are three stages of the Chronos workflow:

1. The cached containers represent the state of a build container after a successful project build.
2. The `replay_build.sh` is able to rebuild a given project from the state of a cached container.
3. The `run_tests.sh` script is able to run the tests of a given project. This should be able to succeed following the running of a `replay_build.sh`.

The stages (2) and (3) must both support running without network connectivity.
Specifically, this means that the `replay_build.sh` must not do tasks e.g. fetch
dependencies, download corpus, or anything of this nature. Similarly, the `run_tests.sh`
must be able to operate completely in a closed network environment.


## Pre-built images.

Chronos cached images are built daily, and pre-built images are available at:

- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-address`
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-coverage`

They can be used as drop-in replacements for the usual `gcr.io/oss-fuzz/<PROJECT>` images.

---

### Overview (`projects/apache-commons-compress/README.md`)

Note that classes that use third party libraries are excluded.
These are either being already fuzzed by oss-fuzz or cannot be
fuzzed effectively. These include:
* BrotliCompressorInputStream - uses Google's Brotli
* DeflateCompressorInputStream - uses JDK's Inflater
* LZMACompressorInputStream - uses XZ for Java
* XZCompressorInputStream - uses XZ for Java
* ZstdCompressorInputStream - uses zstd-jni

---

### Overview (`projects/cel-go/README.md`)

# CEL-Go Fuzzing

This directory contains OSS-Fuzz integration and fuzz targets for CEL-Go:

- `fuzz_compile`: Fuzzes expression compilation and program creation.
- `fuzz_eval`: Structure-aware libprotobuf-mutator fuzzer for variable evaluation.
- `fuzz_pratt_parser`: Differential fuzzer comparing ANTLR and Pratt parser outputs.

---

## Requirements & Setup

OSS-Fuzz uses Docker (or Podman) via `infra/helper.py`.

### Using Podman as an Alternative to Docker

If using `podman` instead of `docker`, create a `docker` symlink on your `PATH`:

```bash
mkdir -p /tmp/bin
ln -sf $(which podman) /tmp/bin/docker
export PATH="/tmp/bin:$PATH"
```

---

## Running Fuzzers Locally

To build and run fuzzers against the remote `cel-expr/cel-go` repository:

```bash
# Navigate to oss-fuzz root directory
cd /local/oss-fuzz

# 1. Build the fuzzer container image and compile fuzz binaries
python3 infra/helper.py build_fuzzers cel-go

# 2. Run a fuzzer (e.g. fuzz_pratt_parser for 30 seconds)
python3 infra/helper.py run_fuzzer cel-go fuzz_pratt_parser -- -max_total_time=30
```

---

## Running Fuzzers Against a Local Clone of `cel-expr/cel-go`

To test local changes or feature branches in your working tree without pushing to GitHub, mount your local repository path (e.g. `/local/cel-go`) into the build container via `build_fuzzers`:

```bash
cd /local/oss-fuzz

# 1. Build fuzzers mounting local /local/cel-go
python3 infra/helper.py build_fuzzers cel-go /local/cel-go

# 2. Run the differential fuzzer
python3 infra/helper.py run_fuzzer cel-go fuzz_pratt_parser -- -max_total_time=30
```

---

### Overview (`projects/cryptofuzz/README.md`)

This OSS-Fuzz project is a composite of multiple cryptographic libraries. It invokes a large amount of implementations for cryptographic primitives across multiple popular libraries, coordinated from a single fuzzing harness.

Its objectives are:

1. To assert programmatic soundness: find memory bugs, crashes and time-outs with the help of sanitizers.
2. To assert semantic soundness: detect invalid output occurring under legal use of the library's API.

One method to detect invalid results (point 2) is to assert equivalence between two or more outputs generated by a single library with the same input (but where each output allowed to be computed differently), aka "self-differential" testing. See [here](https://github.com/openssl/openssl/issues/8675) for a bug found with self-differential testing.

Another method is to compare a result against the result of different library, where both results are expected to be the same. If they are not the same, this indicates a bug in at least one library. This second method is what merits the composite setup of the project; adherence to the normative specification of a cryptographic primitive is implicitly asserted under the assumption that at least one implementation gets it right. Because determining which one of libraries gets it wrong cannot be reliably automated, all library maintainers are notified in this event, so that the cause of discrepancy can be resolved collaboratively.

Library builds embedding optimized assembly language code and those using pure C implementations have been assigned separate fuzzer targets (binaries), because either implementation can have distinct bugs that will not transpire if only the other one is tested.

OpenSSL, BoringSSL and LibreSSL are assigned separate fuzzing targets because their exported symbols largely overlap and can therefore not be bundled into a single binary.

At this time of writing, no differential testing is performed, because support for additional libraries is not ready yet, but I intend to support mbed TLS and libsodium shortly, and support for popular or built-in cryptography implementations for Go, Rust, Java and Javascript is planned.

To further clear things up, at some point in the future, the matrix of support libraries versus fuzzing binaries could look like this:

A binary embedding OpenSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

A binary embedding BoringSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

A binary embedding LibreSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

and another 3 binaries for all of the pure C versions (no assembly language optimizations) of these libraries.

As more libraries are added, I will add a throttle mechanism to Cryptofuzz to ensure that no more than, say, 4 libraries will be called during a single iteration, so that no amount of supported libraries will impact the overall speed of the fuzzing process.

More information can be found at [Cryptofuzz](https://github.com/guidovranken/cryptofuzz).

---

### Overview (`projects/libaom/README.md`)

# Submit a Patch to oss-fuzz repo

## One-time Setup

1.  Create github account if needed (with @google.com email address, preferably)
    and log in.
1.  To allow “git push” to work, you’ll have to add an SSH key:
    https://help.github.com/articles/connecting-to-github-with-ssh/
1.  Go to https://github.com/google/oss-fuzz and click on “Fork”.
1.  Go to your own fork of the repo, which will be at
    https://github.com/\<git_username\>/oss-fuzz
1.  Click on “clone or download” and pick “Clone with SSH” method (I found that
    easier to use for “git push”). Then copy that URL and run “git clone \<URL\>”
    in terminal. Now you have a local repo, and **your fork** of the remote repo
    will be called “**origin**” in your git config.
1.  Configure a remote repo pointing to the **upstream repo**
    (https://github.com/google/oss-fuzz) so that it’s called “**upstream**”:
    *   cd \<local_oss_fuzz_repo_directory\>/oss-fuzz
    *   git remote add upstream git@github.com:google/oss-fuzz.git
    *   git remote -v

NOTE: For trivial changes it's possible to edit the files in the web UI on the
main project and create a commit + pull request from that.

## Workflow for a Pull Request (Patch)

1.  Go to your repo:
    *   cd \<local_oss_fuzz_repo_directory\>/oss-fuzz
1.  Create a new branch:
    *   git checkout master
    *   git checkout -b new_feature_xyz
1.  Make your changes and commit them locally with “git commit”
1.  Push your changes to your fork on github
    *   git push -u origin HEAD
    *   (This will create a branch of the same name “new_feature_xyz” on your
        fork “origin”).
1.  Open your fork in browser and click on “Compare & pull request” and follow
    the prompts.
1.  If changes are requested to the patch:
    *   make changes to the same local branch
    *   commit them locally with “git commit” (but DO NOT amend!)
    *   git push -u origin HEAD
1.  Once pull request is closed:
    *   Delete “new_feature_xyz” branch on your fork using the “Delete branch”
        button on the pull request
    *   Delete local “new_feature_xyz” branch locally with “git checkout master
        && git branch -D new_feature_xyz”
    *   Sync your local repo and your fork with upstream repo:
        *   git checkout master
        *   git fetch upstream
        *   git merge upstream/master
        *   git push origin master

---

### Overview (`projects/skia/README.md`)

When bench testing image_filter_deserialize, it may be useful to have
malloc_limit_mb = 500, and timeout = 10 to find actionable OOM culprits sooner.

When reproducing, add -malloc_limit_mb=100 -rss_limit_mb=0 after the
repro_test to locate where big memory allocations are happening.

    python infra/helper.py reproduce skia image_decode ~/Downloads/foo -malloc_limit_mb=100 -rss_limit_mb=0

---

### Overview (`tools/vscode-extension/README.md`)

# OSS-Fuzz VSCode extension

[OSS-Fuzz](https://github.com/google/oss-fuzz) is a fuzzing toolkit and service for fuzzing open source projects. This VSCode extension provides features and capabilities for interacting with the OSS-Fuzz toolkit and also to compare local changes to the OSS-Fuzz cloud database by way of [Open source fuzz introspection](https://introspector.oss-fuzz.com).

## Features

The VSCode extension is largely driven by commands at this point. The featues of these commands includes:

- Easily setting up OSS-Fuzz
- Templates for easily setting up a new OSS-Fuzz project
- Building arbitrary projects from OSS-Fuzz
- Modify a project from VSCode and test changes in OSS-Fuzz
- Easily extract code coverage of fuzzers, including local-only fuzzers
- Compare local code coverage to what is currently achieved by OSS-Fuzz
- Auto-generation of fuzzer templates

For a full list of commands and their features, please check the commands page.

---

### Overview (`infra/base-images/base-builder/README.md`)

# base-builder
> Abstract base image for project builders.

Every project image supports multiple commands that can be invoked through docker after the image is built:

<pre>
docker run --rm -ti gcr.io/oss-fuzz/<b><i>$project</i></b> <i>&lt;command&gt;</i> <i>&lt;arguments...&gt;</i>
</pre>

# Supported Commands

| Command | Description |
|---------|-------------|
| `compile` (default) | build all fuzz targets
| `/bin/bash` | drop into shell, execute `compile` script to start build.

# Build Configuration

A single build image can build same set of fuzzers in many configurations.
The configuration is picked through one or more environment variables.

| Env Variable     | Description
| -------------    | --------
| `$SANITIZER ("address")` | Specifies predefined sanitizer configuration to use. `address` or `memory` or `undefined`.
| `$SANITIZER_FLAGS` | Specify compiler sanitizer flags directly. Overrides `$SANITIZER`.
| `$COVERAGE_FLAGS` | Specify compiler flags to use for fuzzer feedback coverage.
| `$BUILD_UID` | User id to use while building fuzzers.

## Examples

- *building sqlite3 fuzzer with UBSan (`SANITIZER=undefined`):*


<pre>
docker run --rm -ti -e <i>SANITIZER</i>=<i>undefined</i> gcr.io/oss-fuzz/sqlite3
</pre>


# Image Files Layout

| Location|Env| Description |
|---------| -------- | ----------  |
| `/out/` | `$OUT`         | Directory to store build artifacts (fuzz targets, dictionaries, options files, seed corpus archives). |
| `/src/` | `$SRC`         | Directory to checkout source files |
| `/work/`| `$WORK`        | Directory for storing intermediate files |
| `/usr/lib/libFuzzingEngine.a` | `$LIB_FUZZING_ENGINE` | Location of prebuilt fuzzing engine library (e.g. libFuzzer) that needs to be linked with all fuzz targets.

While files layout is fixed within a container, the environment variables are
provided to be able to write retargetable scripts.


## Compiler Flags

You *must* use special compiler flags to build your project and fuzz targets.
These flags are provided in following environment variables:

| Env Variable    | Description
| -------------   | --------
| `$CC`           | The C compiler binary.
| `$CXX`, `$CCC`  | The C++ compiler binary.
| `$CFLAGS`       | C compiler flags.
| `$CXXFLAGS`     | C++ compiler flags.

Most well-crafted build scripts will automatically use these variables. If not,
pass them manually to the build tool.


# Child Image Interface

## Sources

Child image has to checkout all sources that it needs to compile fuzz targets into
`$SRC` directory. When the image is executed, a directory could be mounted on top
of these with local checkouts using
`docker run -v $HOME/my_project:/src/my_project ...`.

## Other Required Files

Following files have to be added by child images:

| File Location   | Description |
| -------------   | ----------- |
| `$SRC/build.sh` | build script to build the project and its fuzz targets |

---

### Overview (`infra/base-images/base-clang/README.md`)

# base-builder-clang

## Regular build

```
docker build -t gcr.io/oss-fuzz-base/base-clang . 
```

## Full build 
For a build including all binaries and libraries, including with everything built against libcxx, do

```
docker build -t gcr.io/oss-fuzz-base/base-clang-full --build-arg FULL_LLVM_BUILD=1 . 
```

---

### Overview (`infra/base-images/base-runner/README.md`)

# base-runner
> Base image for fuzzer runners.

```bash
docker run -ti gcr.io/oss-fuzz-base/base-runner <command> <args>
```

## Commands

| Command | Description |
|---------|-------------|
| `reproduce <fuzzer_name> <fuzzer_options>` | build all fuzz targets and run specified one with testcase `/testcase` and given options.
| `run_fuzzer <fuzzer_name> <fuzzer_options>` | runs specified fuzzer combining options with `.options` file |
| `test_all.py` | runs every binary in `/out` as a fuzzer for a while to ensure it works. |
| `coverage <fuzzer_name>` | generate a coverage report for the given fuzzer. |

# Examples

- *Reproduce using latest OSS-Fuzz build:*

<pre>
docker run --rm -ti -v <b><i>&lt;testcase_path&gt;</i></b>:/testcase gcr.io/oss-fuzz/<b><i>$PROJECT_NAME</i></b> reproduce <b><i>&lt;fuzzer_name&gt;</i></b>
</pre>

- *Reproduce using local source checkout:*

<pre>
docker run --rm -ti -v <b><i>&lt;source_path&gt;</i></b>:/src/<b><i>$PROJECT_NAME</i></b> \
                    -v <b><i>&lt;testcase_path&gt;</i></b>:/testcase gcr.io/oss-fuzz/<b><i>$PROJECT_NAME</i></b> \
                    reproduce <b><i>&lt;fuzzer_name&gt;</i></b>
</pre>

---

### Overview (`infra/experimental/SystemSan/README.md`)

# System Sanitizers

We use `ptrace` to instrument system calls made by the target program to detect
various vulnerabilities.

## Command injection

This detector currently works by

- Checking if `execve` is called with `/tmp/tripwire` (which comes from our dictionary).
- Checking if `execve` is invoking a shell with invalid syntax. This is likely
  caused by our input.

## Arbitrary file open

TODO: documentation.

## Proof of concept

### Cleanup
Note this will delete /tmp/tripwire if it exists.
```shell
make clean
```

### Run test
Note this will overwrite /tmp/tripwire if it exists.
```shell
make test
```

Look for one of the following lines:

> ===BUG DETECTED: Shell injection===

which indicates the detection of executing the planted `/tmp/tripwire`.


> ===BUG DETECTED: Shell corruption===

which indicates the detection of executing a syntactic erroneous command.


### Command injection PoC in Python with `pytorch-lightning`
With `SystemSan`, [`Artheris`](https://github.com/google/atheris) can detect a shell injection bug in [version v1.5.10 of `pytorch-lightning`](https://github.com/PyTorchLightning/pytorch-lightning/tree/1.5.0).
```shell
make pytorch-lightning-1.5.10
```

### Command injection PoC in JavaScript with `shell-quote`
With `SystemSan`, [`Jsfuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/jsfuzz) can detect a shell corrpution bug in [the latest version (v1.7.3) of `shell-quote`](https://github.com/substack/node-shell-quote) without any seed.
```shell
make node-shell-quote-v1.7.3
```
This is based on [a shell injection exploit report](https://wh0.github.io/2021/10/28/shell-quote-rce-exploiting.html) of [version v1.7.2 of `shell-quote`](https://github.com/substack/node-shell-quote/tree/v1.7.2).
`SystemSan` can also discover the same shell injection bug with a corpus file containing:
```
`:`/tmp/tripwire``:`
```

## Trophies

- <https://github.com/syoyo/tinygltf/issues/368>
- <https://github.com/substack/node-shell-quote/issues/54>

---

### Overview (`infra/experimental/agent-skills/README.md`)

# OSS-Fuzz agent skills

Skills and tooling that let an agent CLI (Gemini CLI or Claude Code) write,
build, and extend OSS-Fuzz fuzzing integrations. The folder ships:

- Six skills that give an agent OSS-Fuzz-specific knowledge.
- `infra/experimental/agent-skills/helper.py`, a wrapper that launches agent
  sessions over one or more OSS-Fuzz projects in parallel.
- `copy_to_global.sh`, an installer that places the skills where your
  agent CLI can find them.

Before running anything in this folder, review the [threat model](#threat-model).
This tooling is experimental and runs agents in unrestricted modes.

## Contents

| Item | Purpose |
|---|---|
| `fuzzing-memory-unsafe-expert/` | Skill: fuzz C/C++ projects |
| `fuzzing-go-expert/` | Skill: fuzz Go projects |
| `fuzzing-rust-expert/` | Skill: fuzz Rust projects (cargo-fuzz) |
| `fuzzing-jvm-expert/` | Skill: fuzz JVM projects (Java/Kotlin/Scala) with Jazzer |
| `fuzzing-python-expert/` | Skill: fuzz Python projects with Atheris |
| `oss-fuzz-engineer/` | Skill: OSS-Fuzz infra workflows (integrate, fix, extend) |
| `infra/experimental/agent-skills/helper.py` | Driver that launches agent sessions per OSS-Fuzz project |
| `copy_to_global.sh` | Installs the skills into `~/.gemini/skills` or `~/.claude/skills` |

See each skill's `SKILL.md` for the detailed guidance the agent receives.

## Prerequisites

- A supported agent CLI installed and on `PATH`:
  [Gemini CLI](https://github.com/google-gemini/gemini-cli) or
  [Claude Code](https://claude.com/claude-code).
- Docker (required by OSS-Fuzz's own `infra/helper.py`, which the agent calls).
- Python 3.
- A local checkout of OSS-Fuzz — `infra/experimental/agent-skills/helper.py`
  resolves the repo root relative to its own location, so run it from this
  checkout.

## Quick start

```bash
# 1. Install the skills into your agent CLI.
./copy_to_global.sh gemini        # or: ./copy_to_global.sh claude

# 2. Confirm the agent CLI is reachable.
gemini --version                  # or: claude --version

# 3. Run a task across one or more OSS-Fuzz projects.
python infra/experimental/agent-skills/helper.py fix-builds open62541 json-c htslib
```

`copy_to_global.sh` **overwrites** any existing skill of the same name in the
target directory.

## How the skills are used

There are two ways the skills get invoked:

1. **Interactively, in your agent CLI.** After `copy_to_global.sh`, the
   skills appear to your agent and are auto-selected when a task matches the
   skill's description. For example, asking the agent to write a Python
   harness will surface `fuzzing-python-expert`. You can use the skills this
   way without ever touching `infra/experimental/agent-skills/helper.py`.

2. **Driven by `infra/experimental/agent-skills/helper.py`.** The helper
   builds task-specific prompts that reference these skills and launches
   non-interactive agent sessions, one per OSS-Fuzz project, in parallel.
   Use this when you want to run the same task across many projects.

The agent makes local changes and writes a per-project report. It does
**not** commit or push — review the diff and reports before you do anything
with the output.

## `infra/experimental/agent-skills/helper.py` commands

Run `python infra/experimental/agent-skills/helper.py <command> --help` for
full flag listings. A summary of the available subcommands:

| Command | Purpose | Example |
|---|---|---|
| `expand-oss-fuzz-projects` | Add new harnesses / improve coverage on existing projects | `python infra/experimental/agent-skills/helper.py expand-oss-fuzz-projects open62541 json-c` |
| `fix-builds` | Diagnose and fix broken project builds | `python infra/experimental/agent-skills/helper.py fix-builds htslib` |
| `fix-broken-builds` | Auto-discover broken projects from the public build status and fix up to `--limit` of them (C/C++ by default) | `python infra/experimental/agent-skills/helper.py fix-broken-builds --limit 50` |
| `run-task` | Run an arbitrary `--task` string per project | `python infra/experimental/agent-skills/helper.py run-task --task "Add a harness for the XML attribute parser" open62541` |
| `add-chronos-support` | Add Chronos support to a project | `python infra/experimental/agent-skills/helper.py add-chronos-support json-c` |
| `integrate-project` | Onboard a new project from a Git URL | `python infra/experimental/agent-skills/helper.py integrate-project https://github.com/org/repo` |
| `clean` | Remove local artifacts from previous agent runs | `python infra/experimental/agent-skills/helper.py clean open62541` |
| `show-prompt` | Print the prompt that would be sent, without launching the agent | `python infra/experimental/agent-skills/helper.py show-prompt fix-builds htslib` |

### Useful behaviors and flags

- **Parallelism.** Sessions run in parallel with `DEFAULT_MAX_PARALLEL = 2`.
  Override with the helper's parallelism flag if your machine can handle
  more concurrent Docker builds.
- **Agent auto-detection.** `infra/experimental/agent-skills/helper.py`
  locates the agent CLI on `PATH` automatically — you do not need to tell
  it whether you are using Gemini CLI or Claude Code.
- **Dry runs.** `show-prompt` prints the exact prompt that would be sent.
  Use it first when trying a new command or task description.
- **Reports and logs.** Each session writes a per-project report locally;
  review these before acting on the agent's changes.

## Typical workflows

**Triage a batch of broken projects**

```bash
python infra/experimental/agent-skills/helper.py show-prompt fix-builds proj1 proj2
python infra/experimental/agent-skills/helper.py fix-builds proj1 proj2
# Review the diff and per-project reports, then commit manually.
```

**Fix a whole batch of broken builds automatically**

Instead of naming projects, let the helper discover them from the public
build status. By default it fixes up to 50 broken **C/C++** *regressions*
(projects that built before and have since broken), skipping new/incomplete
integrations and intentionally-broken example projects:

```bash
# Preview which projects would be selected (no agent launched):
python infra/experimental/agent-skills/helper.py fix-broken-builds --print-only

# Fix up to 50 broken C/C++ projects (2 in parallel by default):
python infra/experimental/agent-skills/helper.py fix-broken-builds --limit 50

# Widen the language set or raise parallelism:
python infra/experimental/agent-skills/helper.py fix-broken-builds \
    --language c,c++,rust --limit 20 -j 4
# Review the diff and per-project reports, then commit manually.
```

**Onboard a new project end-to-end**

```bash
python infra/experimental/agent-skills/helper.py integrate-project https://github.com/org/repo
# The agent uses oss-fuzz-engineer plus the appropriate fuzzing-*-expert
# skill for the project's language.
```

**Expand coverage on a project you already maintain**

```bash
python infra/experimental/agent-skills/helper.py expand-oss-fuzz-projects myproj
```

**Run a custom investigation across several projects**

```bash
python infra/experimental/agent-skills/helper.py run-task \
    --task "Investigate why the XML parser harness has low branch coverage \
            and add targeted harnesses for the attribute-parsing paths." \
    open62541 json-c
```

## Threat model

This is experimental code with a deliberately permissive threat model:

- Agents run in "dangerous"/"yolo" modes and will execute untrusted code.
- Running this tooling means running untrusted code in your environment.
- Only run it in a heavily sandboxed environment and on a trusted network.
- This code does **not** run in OSS-Fuzz production services and is not part
  of the tooling that runs our continuous fuzzing of open source projects.

---

### Overview (`infra/experimental/chronos/README.md`)

# Chronos: rebuilding OSS-Fuzz harnesses using cached builds

Chronos is a utility tooling to enable fast re-building of OSS-Fuzz projects
and analysis of projects' testing infrastructure. This is used by projects,
e.g. [OSS-Fuzz-gen](https://github.com/google/oss-fuzz-gen) to help speed up
valuation processes during fuzzing harness generation.

At the core, Chronos relies on caching containers after project build, in order
to enable fast rebuilding of a project following minor patches, and also enable
running of the tests in a given project. To support this, Chronos creates a snapshot
of a the docker container given project post build completion. This means that all `.o` files, generated
configuations etc. persist in the docker container. These artifacts are then
leverage for future "replay builds" where only a minor part of the project has changed,
e.g. due to some patching on the project. This patching could be e.g. minor adjustments
to the fuzzing harness source code e.g. by [oss-fuzz-gen](https://github.com/google/oss-fuzz-gen).

As such, at the core of Chronos are cached containers that are generated by taking a
snapshot of the container of a project post project build.

Chronos is focused on two features, rebuilding projects fast and running the
tests of a given project.


## Chronos features: fast rebuilding and running the tests of a project

### CLI interface for Chronos

The default route to validating Chronos is using the CLI available in `infra/experimental/chronos/manager.py`

### Chronos feature: Fast rebuilding

Chronos enables rebuilding projects efficiently in contexts where only a small patch
needs to be evalualted in the target. This is achieved by running a replay build script
in the build container, similarly to how a regular `build_fuzzers` command would run, but
with the caveat that the replay build script only performs a subset of the operations
of the original `build.sh`.

The replay build scripts are constructed in two ways: manually or automatically.

#### Option 1: Automated rebuilds

Chronos support automated rebuilding. This is meant as a generic mechanism to enable Chronos support for projects by default. This is achieved by:

1. Calling into a `replay_build.sh` script during the building inside the container [here](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/infra/base-images/base-builder/compile#L292-L296)
2. The `replay_build.sh` calls into `make_build_replayable.py`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/replay_build.sh)
3. `make_build_replayable.py` adjusts the build environment to wrap around common commands, to avoid performing a complete run of `build.sh`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/make_build_replayable.py).

The automated rebuilding works in combination with [Ccache](https://ccache.dev/), in order to facilitate cachine of e.g. `.o` files.
This means that during rebuild mode as long as we have a cacche, we don't need to e.g. run `configure` again and will only have to
rebuild the changed source code.

#### Option 2: Manually provided replay builds

`replay_build.sh` above, is simply just a wrapper script around `build.sh` that aims to enable
fast rebuilding of the project. This `replay_build.sh` can, however, be overwritten in the Dockerfile
of the project's builder image to support a custom approach to fast rebuilding. Two examples of this is [php](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/projects/php/replay_build.sh#L1) and [ffmpeg](https://github.com/google/oss-fuzz/blob/master/projects/ffmpeg/replay_build.sh#L1).

Providing a manual `replay_build.sh` is likely more efficient at build time and can help speed up the process. Automated replay build scripts can also be erroneous.


#### Testing the validity of a replay build

The Chronos manager can use the `manager.py` to validate the validity of a
replay build for a given project:

```sh
python3 infra/experimental/chronos/manager.py check-replay tinyobjloader
```

If the above command fails for the relevant project, then the replay build feature
does not work for the given project.

### Chronos feature:  Running tests of a project

The second part of Chronos is a feature to enable running the tests of a given
project. This is done by way of a script `run_tests.sh`. Samples of
this script include [jsonnet](https://github.com/google/oss-fuzz/blob/master/projects/jsonnet/run_tests.sh#L1) and [tinyobjloader](https://github.com/google/oss-fuzz/blob/master/projects/tinyobjloader/run_tests.sh#L1).


#### Run tests constraints

1. The `run_tests.sh` main task is to run the tests of a project and return `0` upon success and non-null otherwise.
2. The `run_tests.sh` script must leave the main repository in the state as it was prior to the execution of `run_tests.sh` relative to `git diff` (or similar diff features of other version control systems).

#### Testing the validity of run_tests.sh

The Chronos manager can use the `manager.py` to validate the validity of a
`run_tests.sh` script:

```sh
python3 infra/experimental/chronos/manager.py check-tests json-c
```


### Constraints imposed on replay_build.sh and run_tests.sh

At the core of chronos are the two scripts `replay_build.sh` and `run_tests.sh`. We have a default
mechanism for `replay_build.sh` so it's not strictly necessary to have a custom one, although it will
likely improve speed and maybe correctness by providing one.

There are three stages of the Chronos workflow:

1. The cached containers represent the state of a build container after a successful project build.
2. The `replay_build.sh` is able to rebuild a given project from the state of a cached container.
3. The `run_tests.sh` script is able to run the tests of a given project. This should be able to succeed following the running of a `replay_build.sh`.

The stages (2) and (3) must both support running without network connectivity.
Specifically, this means that the `replay_build.sh` must not do tasks e.g. fetch
dependencies, download corpus, or anything of this nature. Similarly, the `run_tests.sh`
must be able to operate completely in a closed network environment.


## Pre-built images.

Chronos cached images are build daily, and pre-built images are available at:

- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-address`
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-coverage`

They can be used as drop-in replacements for the usual `gcr.io/oss-fuzz/<PROJECT>` images.

---

### Overview (`infra/experimental/mcp/README.md`)

# OSS-Fuzz MCP

This is an experimental implementation of an MCP server that enables use of
OSS-Fuzz tools. You can use it to solve various common OSS-Fuzz tasks.

At this stage, this is purely experimental code.


## Threat model for running

This is experimental code and has an open threat model. By design, the MCP server
executes untrusted code. As such, when running this tool you
should assume you will be running untrusted code on your machine. You should
only run this in a trusted environment and on a trusted network. In practice,
this means you must run this in a heavily sandboxed environment, and from a
security perspective if you run this tool you will run untrusted code in
your environment.

This code does not run in OSS-Fuzz production services and is not part of the
tooling that runs our continuous fuzzing of open source projects.

## Running the Service

```sh
python3.12 -m venv .venv
. .venv/bin/active
python3 -m pip install -r ./requirements.txt



# Start server in one  terminal
python3 ./oss_fuzz_server.py


# Start client
python3 ./client.py fix-build --projects abseil-py
```

---

### Overview (`projects/example/my-api-repo/README.md`)

Example of [OSS-Fuzz ideal integration](https://google.github.io/oss-fuzz/advanced-topics/ideal-integration/).

This directory contains an example software project that has most of the traits of [ideal](https://google.github.io/oss-fuzz/advanced-topics/ideal-integration/) support for fuzzing. 

## Files in my-api-repo
Imagine that these files reside in your project's repository:

* [my_api.h](my_api.h): and [my_api.cpp](my_api.cpp) implement the API we want to test/fuzz. The function `DoStuff()` inside [my_api.cpp](my_api.cpp) contains a bug. (Find it!)
* [do_stuff_unittest.cpp](do_stuff_unittest.cpp): is a unit test for `DoStuff()`. Unit tests are not necessary for fuzzing but are generally a good practice.
* [do_stuff_fuzzer.cpp](do_stuff_fuzzer.cpp): is a [fuzz target](https://llvm.org/docs/LibFuzzer.html#fuzz-target) for `DoStuff()`.
* [do_stuff_test_data](do_stuff_test_data): corpus directory for [do_stuff_fuzzer.cpp](do_stuff_fuzzer.cpp).
* [do_stuff_fuzzer.dict](do_stuff_fuzzer.dict): a [fuzzing dictionary file](https://google.github.io/oss-fuzz/getting-started/new-project-guide#dictionaries) for `DoStuff()`. Optional, but may improve fuzzing in many cases. 
* [Makefile](Makefile): is a build file (the same can be done with other build systems):
  * accepts external compiler flags via `$CC`, `$CXX`, `$CFLAGS`, `$CXXFLAGS`
  * accepts external fuzzing engine via `$LIB_FUZZING_ENGINE`, by default uses [standalone_fuzz_target_runner.cpp](standalone_fuzz_target_runner.cpp)
  * builds the fuzz target(s) and their corpus archive(s)
  * `make check` executes [do_stuff_fuzzer.cpp](do_stuff_fuzzer.cpp) on [`do_stuff_test_data/*`](do_stuff_test_data), thus ensures that the fuzz target is up to date and uses it as a regression test.
* [standalone_fuzz_target_runner.cpp](standalone_fuzz_target_runner.cpp): is a simple standalone runner for fuzz targets. You may use it to execute a fuzz target on given files w/o having to link in libFuzzer or other fuzzing engine.

## Files in OSS-Fuzz repository
* [oss-fuzz/projects/example](..)
  * [Dockerfile](../Dockerfile): sets up the build environment
  * [build.sh](../build.sh): builds the fuzz target(s). The smaller this file the better (most of the logic should be inside the project's build system).
  * [project.yaml](../project.yaml): short project description and contact info.

## Example bug
Example bug report filed automatically: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1562

---

### Overview (`infra/base-images/base-builder/indexer/README.md`)

# Indexer snapshot builds

This directory provides the tooling to be able to build "indexed" OSS-Fuzz
builds, which are snapshots which provide the binary, source code, and a source
code index.

Snapshots are also built by our infrastructure and available at
`gs://clusterfuzz-builds/indexer_indexes`.

## Building project snapshots

```bash
python infra/helper.py build_image <project>
python infra/helper.py index <project>

# Only build snapshots for `target1` and `target2`.
python infra/helper.py index --targets 'target1,target2' <project>

# Drop into /bin/bash instead of automatically running /opt/indexer/index_build.py.
python infra/helper.py index --shell <project>

# Add additional docker args.
python infra/helper.py index --docker_arg="-eFOO=123" --docker_arg="-eBAR=456" <project>

# Pass through flags to the entrypoint.
python infra/helper.py index <project> -- --target-args '123'
```

The resulting snapshots will be found in `<oss-fuzz checkout>/build/out/<project>`.

## Development

For faster local development on the scripts in this directory, we can mount in
everything inside this directory to overwrite the scripts in the base image by
passing `--dev` to the index command.

If the `indexer` binary does not exist, a prebuilt binary is
[downloaded](https://clusterfuzz-builds.storage.googleapis.com/oss-fuzz-artifacts/indexer).

```
cd $OSS_FUZZ_CHECKOUT
python infra/helper.py index --dev <PROJECT_NAME>
```

The resulting snapshots will be found in `<oss-fuzz checkout>/build/out/<project>`.

## Testing

We have some basic tests to make sure the snapshots we're generating have the correct format.

For this to work, you need to run `python infra/helper.py index --dev <PROJECT_NAME>` at least
once, or make sure you have the `indexer` binary in this directory.

```
sudo INDEX_BUILD_TESTS=1 python3 -m unittest index_build_test
```

---

### Overview (`infra/experimental/sanitizers/ExecSan/README.md`)

# Moved

This has moved to <https://github.com/google/oss-fuzz/tree/master/infra/experimental/SystemSan>.

---

### Overview (`infra/base-images/base-builder/sanitizers/pysecsan/README.md`)

# pysecsan

Security sanitizers for vulnerability detection during runtime.

---

### Index (`docs/index.md`)

---
layout: default
title: OSS-Fuzz
permalink: /
nav_order: 1
has_children: true
has_toc: false
---

# OSS-Fuzz

[Fuzz testing] is a well-known technique for uncovering programming errors in
software. Many of these detectable errors, like [buffer overflow], can have
serious security implications. Google has found [thousands] of security
vulnerabilities and stability bugs by deploying [guided in-process fuzzing of
Chrome components], and we now want to share that service with the open source
community.

[Fuzz testing]: https://en.wikipedia.org/wiki/Fuzz_testing
[buffer overflow]: https://en.wikipedia.org/wiki/Buffer_overflow
[thousands]: https://bugs.chromium.org/p/chromium/issues/list?q=label%3AStability-LibFuzzer%2CStability-AFL%20-status%3ADuplicate%2CWontFix&can=1
[guided in-process fuzzing of Chrome components]: https://security.googleblog.com/2016/08/guided-in-process-fuzzing-of-chrome.html

In cooperation with the [Core Infrastructure Initiative] and the [OpenSSF],
OSS-Fuzz aims to make common open source software more secure and stable by
combining modern fuzzing techniques with scalable, distributed execution.
Projects that do not qualify for OSS-Fuzz (e.g. closed source) can run their own
instances of [ClusterFuzz] or [ClusterFuzzLite].

[Core Infrastructure Initiative]: https://www.coreinfrastructure.org/
[OpenSSF]: https://www.openssf.org/

We support the [libFuzzer], [AFL++], [Honggfuzz], and [Centipede] fuzzing engines in
combination with [Sanitizers], as well as [ClusterFuzz], a distributed fuzzer
execution environment and reporting tool.

[libFuzzer]: https://llvm.org/docs/LibFuzzer.html
[AFL++]: https://github.com/AFLplusplus/AFLplusplus
[Honggfuzz]: https://github.com/google/honggfuzz
[Centipede]: https://github.com/google/centipede
[Sanitizers]: https://github.com/google/sanitizers
[ClusterFuzz]: https://github.com/google/clusterfuzz
[ClusterFuzzLite]: https://google.github.io/clusterfuzzlite/

Currently, OSS-Fuzz supports C/C++, Rust, Go, Python, Java/JVM code, JavaScript
and Lua. Other languages supported by [LLVM] may work too. OSS-Fuzz supports fuzzing x86_64
and i386 builds.

[LLVM]: https://llvm.org


## Project history
OSS-Fuzz was launched in 2016 in response to the
[Heartbleed] vulnerability, discovered in [OpenSSL], one of the
most popular open source projects for encrypting web traffic. The vulnerability
had the potential to affect almost every internet user, yet was caused by a
relatively simple memory buffer overflow bug that could have been detected by
fuzzing—that is, by running the code on randomized inputs to intentionally cause
unexpected behaviors or crashes. At the time, though, fuzzing
was not widely used and was cumbersome for developers, requiring extensive
manual effort.

Google created OSS-Fuzz to fill this gap: it's a free service that runs fuzzers
for open source projects and privately alerts developers to the bugs detected.
Since its launch, OSS-Fuzz has become a critical service for the open source
community, growing beyond C/C++ to
detect problems in memory-safe languages such as Go, Rust, and Python.

[Heartbleed]: https://heartbleed.com/ 
[OpenSSL]: https://www.openssl.org/

## Learn more about fuzzing

This documentation describes how to use OSS-Fuzz service for your open source
project. To learn more about fuzzing in general, we recommend reading [libFuzzer
tutorial] and the other docs in [google/fuzzing] repository. These and some
other resources are listed on the [useful links] page.

[google/fuzzing]: https://github.com/google/fuzzing/tree/master/docs
[libFuzzer tutorial]: https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md
[useful links]: {{ site.baseurl }}/reference/useful-links/#tutorials

## Trophies
As of August 2023, OSS-Fuzz has helped identify and fix over [10,000] vulnerabilities and [36,000] bugs across [1,000] projects.

[10,000]: https://bugs.chromium.org/p/oss-fuzz/issues/list?q=Type%3DBug-Security%20label%3Aclusterfuzz%20-status%3ADuplicate%2CWontFix&can=1
[36,000]: https://bugs.chromium.org/p/oss-fuzz/issues/list?q=Type%3DBug%20label%3Aclusterfuzz%20-status%3ADuplicate%2CWontFix&can=1
[1,000]: https://github.com/google/oss-fuzz/tree/master/projects

---

### AI Patches (Beta) (`docs/AI patches (beta).md`)

---
layout: default
title: AI patches (beta)
nav_order: 3
permalink: /ai-patches-beta/
---

# AI patches (beta)

For [certain classes](#scope-of-beta) of vulnerabilities, OSS-Fuzz now delivers high-quality, AI-proposed patches along with bugs. The patches are generated by [CodeMender](https://deepmind.google/blog/introducing-codemender-an-ai-agent-for-code-security/), an AI coding security agent from Google DeepMind.

This document describes the benefits of this new functionality, its scope, and how you can use it.

# Why AI-proposed patches?

Agentic code scanning has the potential to improve the security posture of the open-source ecosystem. But we know that open source maintainers are overwhelmed by AI-generated submissions. Maintainers need new ways to take advantage of the time-saving power of AI: secure bug fixes that don’t need intensive review to validate.

Through OSS-Fuzz’s use of CodeMender, you get ready-made patches that help relieve the burden of securing your projects. The patches reduce your risk exposure by decreasing the time to getting a viable fix deployed.

# Scope of beta {#scope-of-beta}

You will only receive an AI-proposed patch along with a bug if the following are true:

* You have already onboarded your project to OSS-Fuzz  
* Your project’s submission policy doesn’t prohibit AI-generated submissions  
* The bug is related to memory safety in a C or C++ project  
* OSS-Fuzz found a reproducible vulnerability

# How it works

When OSS-Fuzz finds a vulnerability, the system feeds the crash details and source code context directly into CodeMender. The CodeMender agent analyzes the flaw to develop multiple patch attempts, choosing the highest-quality patch candidate to promote to the next stage of the process. 

# Ensuring patch quality

Before sending you an AI-proposed patch, OSS-Fuzz follows a rigorous patch delivery process:

* We proactively check your repository's guidelines before engaging; for example, if your project restricts AI code, we honor that choice and withhold submissions entirely.   
* We verify that each patch works, testing every fix in an isolated environment to prove that it compiles cleanly and successfully resolves the crash.   
* As a temporary measure during this beta phase, Google engineers known as *patch shepherds* personally review proposed patches to ensure they’re up to standard.

As part of their role, patch shepherds do the following:

1. Review candidate patchsets for a given OSS-Fuzz vulnerability report, selecting a single patch to be submitted while giving feedback to the CodeMender team.   
2. Contact maintainers (in the context of OSS-Fuzz vulnerability reports) to include patches and land fixes  
3. Gather feedback from maintainers on what they want to see in vulnerability reports, patches & other supporting content, which is used to improve the UX for code maintainers and the performance of CodeMender as a patch generation agent.

# Signing up and opting out

If your project is already onboarded to OSS-Fuzz:

* **To sign up**: You don’t need to do anything. When OSS-Fuzz finds a vulnerability, it will begin to deliver AI-proposed patches along with bugs that are in scope of the beta.  
* **To opt out**: Update your submission policy to prohibit AI-generated submissions. Our systems will respect your policy. You can also [opt out directly](https://google.github.io/oss-fuzz/getting-started/new-project-guide/#disable_remediation).

If your project is not onboarded, [follow our guidance](https://google.github.io/oss-fuzz/getting-started/accepting-new-projects/) to onboard and configure your project for OSS-Fuzz. You’ll start receiving AI-proposed patches automatically, unless you opt out.

# Reviewing AI-proposed patches

We recommend that you approach AI-proposed patches with the same rigor you would use for any other proposed submission. We have updated our [bug fixing guidance](https://google.github.io/oss-fuzz/advanced-topics/bug-fixing-guidance) to help you account for AI-proposed patches when you prioritize bugs. 

# Send feedback

Recipients of AI-proposed patches can provide insights and feedback to internal reviewers by collaborating through their preferred disclosure channels and the OSS Fuzz Buganizer Issue. 

For broader feedback, participants can also open an OSS-Fuzz [Github issue](https://github.com/google/oss-fuzz).

---

###  Config.Yml (`docs/_config.yml`)

# Welcome to Jekyll!
#
# This config file is meant for settings that affect your whole blog, values
# which you are expected to set up once and rarely edit after that. If you find
# yourself editing this file very often, consider using Jekyll's data files
# feature for the data you need to update frequently.
#
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.

# Site settings
# These are used to personalize your new site. If you look in the HTML files,
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}.
title: OSS-Fuzz
description: Documentation for OSS-Fuzz
baseurl: "/oss-fuzz" # the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site, e.g. http://example.com

# Build settings
markdown: kramdown
remote_theme: pmarsceill/just-the-docs
search_enabled: true

ga_tracking: G-LRX1V3S5P

aux_links:
  "OSS-Fuzz on GitHub":
    - https://github.com/google/oss-fuzz

# Exclude from processing.
exclude:
  - Gemfile
  - Gemfile.lock
  - node_modules
  - vendor/bundle/
  - vendor/cache/
  - vendor/gems/
  - vendor/ruby/

---

### Faq (`docs/faq.md`)

---
layout: default
title: FAQ
nav_order: 8
permalink: /faq/
---

# Frequently Asked Questions

- TOC
{:toc}
---

## Where can I learn more about fuzzing?

We recommend reading [libFuzzer tutorial] and the other docs in [google/fuzzing]
repository. These and some other resources are listed on the
[useful links]({{ site.baseurl }}/reference/useful-links/#tutorials) page.

[google/fuzzing]: https://github.com/google/fuzzing/tree/master/docs
[libFuzzer tutorial]: https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md

## What kind of projects are you accepting?

We accept established projects that have a critical impact on infrastructure and
user security. We will consider each request on a case-by-case basis, but some
things we keep in mind are:

  - Exposure to remote attacks (e.g. libraries that are used to process
    untrusted input).
  - Number of users/other projects depending on this project.

We hope to relax this requirement in the future though, so keep an eye out even
if we are not able to accept your project at this time!

## How can I find potential fuzz targets in my open source project?

You should look for places in your code that:

  - consume un-trusted data from users or from the network.
  - consume complex input data even if it's 'trusted'.
  - use an algorithm that has two or more implementations
    (to verify their equivalence).
  - look for existing fuzz target [examples](https://github.com/google/oss-fuzz/tree/master/projects)
    and find similarities.

## Where can I store fuzz target sources and the build script if it's not yet accepted upstream?

Fuzz target sources as well as the build script may temporarily live inside the
`projects/<your_project>` directory in the OSS-Fuzz repository. Note that we do
not accept integrations that rely on forked repositories. Refer to the
[ideal integration guide] for the preferred long term solution.

## My project is not open source. Can I use OSS-Fuzz?

You cannot use OSS-Fuzz, but you can use [ClusterFuzz] which OSS-Fuzz is based
on. ClusterFuzz is an open-source fuzzing infrastructure that you can deploy in
your own environment and run continuously at scale.

OSS-Fuzz is a production instance of ClusterFuzz, plus the code living in
[OSS-Fuzz repository]: build scripts, `project.yaml` files with contacts, etc.

[OSS-Fuzz repository]: https://github.com/google/oss-fuzz

## Why do you use a [different issue tracker](https://bugs.chromium.org/p/oss-fuzz/issues/list) for reporting bugs in OSS projects?

Security access control is important for the kind of issues that OSS-Fuzz detects,
hence why by default issues are only opened on the OSS-Fuzz tracker.
You can opt-in to have them on Github as well by adding the `file_github_issue`
attribute to your `project.yaml` file. Note that this is only for visibility's
purpose, and that the actual details can be found by following the link to the
OSS-Fuzz tracker.

## Why do you require a Google account for authentication?

Our [ClusterFuzz]({{ site.baseurl }}/further-reading/clusterfuzz) fuzzing
infrastructure and [issue tracker](https://bugs.chromium.org/p/oss-fuzz/issues/list)
require a Google account for authentication. Note that an alternate email
address associated with a Google account does not work due to appengine api
limitations.

## Why do you use Docker?

Building fuzzers requires building your project with a fresh Clang compiler and
special compiler flags.  An easy-to-use Docker image is provided to simplify
toolchain distribution. This also simplifies our support for a variety of Linux
distributions and provides a reproducible environment for fuzzer
building and execution.

## How do you handle timeouts and OOMs?

If a single input to a [fuzz target]({{ site.baseurl }}/reference/glossary/#fuzz-target)
requires more than **~25 seconds** or more than **2.5GB RAM** to process, we
report this as a timeout or an OOM (out-of-memory) bug
(examples: [timeouts](https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&q=%22Crash+Type%3A+Timeout%22),
[OOMs](https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&q="Crash+Type%3A+Out-of-memory")).
This may or may not be considered as a real bug by the project owners,
but nevertheless we treat all timeouts and OOMs as bugs
since they significantly reduce the efficiency of fuzzing.

Remember that fuzzing is executed with AddressSanitizer or other
sanitizers which introduces a certain overhead in RAM and CPU.

We currently do not have a good way to deduplicate timeout or OOM bugs.
So, we report only one timeout and only one OOM bug per fuzz target.
Once that bug is fixed, we will file another one, and so on.

## Can I change the default timeout and OOM for a fuzz target?

Yes, you can. For this, create a fuzz target options file named `<fuzz-target>.options`,
where `<fuzz-target>` is the executable file name of the fuzz target, in the same
directory as your `project.yaml`. The options file can contain fuzzer-specific
configuration values, such as:

```
[libfuzzer]
rss_limit_mb = 6000
timeout = 30
```

## My library gracefully handles allocation failures, why are OOMs reported?

OOM detection is done *not* by instrumenting memory allocation routines such as `malloc`
to have them return NULL, but using a separate watchdog thread that measures the resident
set size (RSS) on a periodic basis. Therefore, your fuzz target might successfully
allocate more than the configured max RSS, and yet get killed shortly afterwards.

The only reliable way to avoid this is for your fuzz target to use a custom allocator
that will prevent allocating more memory than a given limit. You can find a more
detailed discussion of this topic, as well as links to the solution implemented
by a specific project, in [this issue](https://github.com/google/oss-fuzz/issues/1830).

## Can I launch an additional process (e.g. a daemon) from my fuzz target?

No. In order to get all the benefits of in-process, coverage-guided fuzz testing,
it is required to run everything inside a single process. Any child processes
created outside the main process introduces heavy launch overhead and is not
monitored for code coverage.

Another rule of thumb is: "the smaller fuzz target is, the better it is". It is
expected that your project will have many fuzz targets to test different
components, instead of a single fuzz target trying to cover everything.
Think of fuzz target as a unit test, though it is much more powerful since it
helps to test millions of data permutations rather than just one.

## What if my fuzz target finds a bug in another project (dependency) ?

Every bug report has a crash stack-trace that shows where the crash happened.
Using that, you can debug the root cause and see which category the bug falls in:

- If this is a bug is due to an incorrect usage of the dependent project's API
in your project, then you need to fix your usage to call the API correctly.
- If this is a real bug in the dependent project, then you should CC the
maintainers of that project on the bug. Once CCed, they will get automatic
access to all the information necessary to reproduce the issue. If this project
is maintained in OSS-Fuzz, you can search for contacts in the respective
project.yaml file.

## What if my fuzzer does not find anything?

If your fuzz target is running for many days and does not find bugs or new
coverage, it may mean several things:
- We've covered all reachable code. In order to cover more code we need more
  fuzz targets.
- The [seed corpus]({{ site.baseurl }}/getting-started/new-project-guide#seed-corpus) is not good enough and the
  fuzzing engine(s) are not able to go deeper based on the existing seeds.
  Need to add more seeds.
- There is some crypto/crc stuff in the code that will prevent any fuzzing
  engine from going deeper, in which case the crypto should be disabled in
  [fuzzing mode](https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode).
  Examples: [openssl](https://github.com/openssl/openssl/tree/master/fuzz#reproducing-issues),
  [boringssl](https://boringssl.googlesource.com/boringssl/+/HEAD/FUZZING.md#Fuzzer-mode)
- It is also possible that the fuzzer is running too slow
  (you may check the speed of your targets at https://oss-fuzz.com/)

In either case, look at the
[coverage reports]({{ site.baseurl }}/further-reading/clusterfuzz#coverage-reports)
for your target(s) and figure out why some parts of the code are not covered.

## What if my fuzzer does not find new coverage or bugs after a while?

It is common for fuzzers to plateau and stop finding new coverage or bugs.
[Fuzz Introspector](https://github.com/ossf/fuzz-introspector) helps you
evaluate your fuzzers' performance.
It can help you identify bottlenecks causing your fuzzers to plateau.
It provides aggregated and individual fuzzer reachability and coverage reports.
Developers can either introduce a new fuzz target or modify an existing one to
reach previously unreachable code.
Here are
[case studies](https://github.com/ossf/fuzz-introspector/blob/main/doc/CaseStudies.md)
where Fuzz Introspector helped developers improve fuzzing of a project.
Fuzz Introspector reports are available on the [OSS-Fuzz homepage](https://oss-fuzz.com/)
or through this [index](http://oss-fuzz-introspector.storage.googleapis.com/index.html).

Developers can also use Fuzz Introspector on their local machines.
Detailed instructions are available
[here](https://github.com/ossf/fuzz-introspector/tree/main/oss_fuzz_integration#build-fuzz-introspector-with-oss-fuzz).

## Why are code coverage reports public?

We work with open source projects and try to keep as much information public as
possible. We believe that public code coverage reports do not put users at risk,
as they do not indicate the presence of bugs or lack thereof.

## Why is the coverage command complaining about format compatibility issues?

This may happen if the Docker images fetched locally become out of sync. Make
sure you run the following command to pull the most recent images:

```bash
$ python3 infra/helper.py pull_images
```

Please refer to
[code coverage]({{ site.baseurl }}/advanced-topics/code-coverage/) for detailed
information on code coverage generation.

## What happens when I rename a fuzz target ?

If you rename your fuzz targets, the existing bugs for those targets will get
closed and fuzzing will start from scratch from a fresh corpora
(seed corpus only). Similar corpora will get accumulated over time depending on
the number of cpu cycles that original fuzz target has run. If this is not
desirable, make sure to copy the accumulated corpora from the original fuzz
target (instructions to download
[here]({{ site.baseurl }}/advanced-topics/corpora/#downloading-the-corpus)) and
restore it to the new GCS location later (instruction to find the
new location [here]({{ site.baseurl }}/advanced-topics/corpora/#viewing-the-corpus-for-a-fuzz-target)).

## Does OSS-Fuzz support AFL or honggfuzz or Centipede?

OSS-Fuzz *uses* the following
[fuzzing engines]({{ site.baseurl }}/reference/glossary/#fuzzing-engine):

1. [libFuzzer](https://llvm.org/docs/LibFuzzer.html).
1. [AFL++](https://github.com/AFLplusplus/AFLplusplus), an improved and
   well-maintained version of [AFL](https://lcamtuf.coredump.cx/afl/).
1. [Honggfuzz](https://github.com/google/honggfuzz).
1. [Centipede (Experimental)](https://github.com/google/centipede).

Follow the [new project guide] and OSS-Fuzz will use all its fuzzing engines
on your code.

## What are the specs on your machines?

OSS-Fuzz builders have 32CPU/28.8GB RAM.

Fuzzing machines only have a single core and fuzz targets should not use more
than 2.5GB of RAM.

## Are there any restrictions on using test cases / corpora generated by OSS-Fuzz?

No, you can freely use (i.e. share, add to your repo, etc.) the test cases and
corpora generated by OSS-Fuzz. OSS-Fuzz infrastructure is fully open source
(including [ClusterFuzz], various fuzzing engines, and other dependencies). We
have no intent to restrict the use of the artifacts produced by OSS-Fuzz.

[ClusterFuzz]: https://github.com/google/clusterfuzz
[new project guide]: {{ site.baseurl }}/getting-started/new-project-guide/
[ideal integration guide]: {{ site.baseurl }}/getting-started/new-project-guide/

---

### Glossary (`docs/glossary.md`)

This page has moved [here](https://google.github.io/oss-fuzz/reference/glossary/)

---

### Ideal Integration (`docs/ideal_integration.md`)

This page has moved [here](https://google.github.io/oss-fuzz/advanced-topics/ideal-integration)

---

### New Project Guide (`docs/new_project_guide.md`)

This page has moved [here](https://google.github.io/oss-fuzz/getting-started/new-project-guide/)

---

### Reproducing (`docs/reproducing.md`)

This page has moved [here](https://google.github.io/oss-fuzz/advanced-topics/reproducing)

---

### Advanced Topics Advanced Topics (`docs/advanced-topics/advanced_topics.md`)

---
layout: default
title: Advanced topics
has_children: true
nav_order: 4
permalink: /advanced-topics/
---

# Advanced topics

---

### Advanced Topics Bug Fixing Guidance (`docs/advanced-topics/bug_fixing_guidance.md`)

---
layout: default
title: Bug fixing guidance
nav_order: 6
permalink: /advanced-topics/bug-fixing-guidance
---

# Bug fixing guidance
{: .no_toc}

This page provides brief guidance on how to prioritise and fix bugs reported by
OSS-Fuzz.

- TOC
{:toc}

## Threat modelling
In general the severity of an issue reported by OSS-Fuzz must be determined
relative to the threat model of the project under analysis. Therefore, although
the fuzzers OSS-Fuzz makes an effort into determining the severity of the bug
the true severity of the bug depends on the threat model of the project.

## Bug prioritisation

### Security issues
These are the top priority of solving. A label is attached to these on
the OSS-Fuzz testcase page and you can also search up all of these on monorail
using the search pattern `-Bug=security`.

Issues of this kind include issues reported by Address Sanitizer, e.g.
heap-based buffer overflows, stack-based buffer overflows and use-after-frees.

### AI-proposed patches

If a bug comes with an AI-proposed patch, you can have confidence that the patch passed internal quality control review, and that bug may require less time to fix. Consider this decreased cost in your prioritization methodology.

### Functional issues and memory leaks
These are issues that in general can tamper with the functionality of the
application. The bugs that have highest priority in this case are those that
can be easily triggered by an untrusted user of the project.

### Timeouts and out-of-memory
These are in general the least prioritised issues to solve.

### Bug prioritisation of non C/C++ projects
Currently there is no prioritisation of bugs in non C/C++ projects. As such, in
this scenario it is crucial you do the analysis yourself relative to the threat
model of your project.

## Non-reproducible bugs
OSS-Fuzz will report some bugs that are labeled `Reliably reproduces: NO` and
these can be tricky to deal with. A non-reproducible bug is an issue that
OSS-Fuzz did indeed discover, however, OSS-Fuzz is unable to reproduce the bug
with `python3 infra/helper.py reproduce`. In general, our suggestion is to do
analysis of the bug and determine whether there in fact is an issue.

The non-reproducible bugs can be of varying nature. Some of these bugs will be
due to some internal state of the target application being manipulated over the
cause of several executions of the fuzzer function. This could be several
hundreds or even thousands of executions and the bug may not be reproducible by
a single fuzzer test-case, however, there is indeed a bug in the application.
There are other reasons why bugs may be non-reproducible and in general any
non-determinism introduced into the application can have an effect on this.

In the case of non-reproducible bugs our advice is to put effort into analysing
the potential bug and also assess whether this is due to some internal state
that persists between each fuzz run. If that is indeed the case then we also
suggest investigating whether the fuzzer can be written such that the internal
state in the code will be reset between each fuzz run.

## Should all reported issues be solved?
It is reported by some project maintainers that fixing timeout issues reported
by OSS-Fuzz can increase the complexity of the project’s source code. The
result of this is that maintainers put effort into solving a timeout issue and
the fix results in additional complexity of the project. The question is
whether in a scenario like this if the overall result actually improves the
state of the application.

In order to answer this question we must assess the issue relative to the
threat model. Following the timeout anecdote then some timing issues can have
severe security implications. For example, if the timeout issue can cause
manipulation of control-flow then the timing issue may be of high security
severity. As such, it is difficult to say in the general case whether or not
some bugs should not be solved, as it should be analysed and determined on a
project-by-project basis.

In the event that a bug is reported by OSS-Fuzz that is not relevant to
security or reliability of the application then there may still be a point to
fixing the bug. For example, if the issue is often run into by the fuzzer then
the fuzzer may have difficulty exploring further code in the target, and thus
fixing the bug will allow the fuzzer to explore further code. In this case some
suggested examples of resolving the issue could be:
* Perform a hot-patch that is only applied during fuzzer executions and does
not overcomplicate the project’s code.
* Patch the code of the fuzzer to avoid the timeout. For example, some fuzzers
restrict the size of the input to avoid certain deep recursions or
time-intensive loops.
* Patch the code in the target despite complicating things.

---

### Advanced Topics Code Coverage (`docs/advanced-topics/code_coverage.md`)

---
layout: default
title: Code coverage
parent: Advanced topics
nav_order: 2
permalink: /advanced-topics/code-coverage/
---

# Code Coverage
{: .no_toc}

For projects written in C/C++, Rust, Go, Swift or Java and other JVM-based languages,
you can generate code coverage reports using Clang source-based code coverage.
This page walks you through the basic steps.
For more details on C/C++ coverage, see [Clang's documentation].

Code coverage reports generation for other languages is not supported yet.

- TOC
{:toc}
---

## Pull the latest Docker images

Docker images get regularly updated with a newer version of build tools, build
configurations, scripts, and other changes. We recommend you pull the most
recent images by running the following command:

```bash
$ python3 infra/helper.py pull_images
```

## Build fuzz targets

Code coverage report generation requires a special build configuration to be
used. To create a code coverage build for your project, run these commands:

```bash
$ python3 infra/helper.py build_image $PROJECT_NAME
$ python3 infra/helper.py build_fuzzers --sanitizer=coverage $PROJECT_NAME
```

## Establish access to GCS

To get a good understanding of fuzz testing quality, you should generate code
coverage reports by running fuzz targets against the corpus
aggregated by OSS-Fuzz. Set up `gcloud` and ensure that you have access to the
corpora by doing the following:

* Install the [gcloud tool].
* Check whether you have access to the corpus for your project:

```bash
$ gcloud storage ls gs://${PROJECT_NAME}-corpus.clusterfuzz-external.appspot.com/
```

If you see an authorization error from the command above, run this:

```bash
$ gcloud auth login
```

and try again. Once `gcloud storage` works, you can run the report generation.

## Generate code coverage reports

### Full project report

If you want to generate a code coverage report using the corpus aggregated on
OSS-Fuzz, run this command:

```bash
$ python3 infra/helper.py coverage $PROJECT_NAME
```

If you want to generate a code coverage report using the corpus you have
locally, copy the corpus into the
`build/corpus/$PROJECT_NAME/<fuzz_target_name>/` directories for each fuzz
target, then run this command:

```bash
$ python3 infra/helper.py coverage --no-corpus-download $PROJECT_NAME
```

### Single fuzz target

You can generate a code coverage report for a particular fuzz target by using
the `--fuzz-target` argument:

```bash
$ python3 infra/helper.py coverage --fuzz-target=<fuzz_target_name> $PROJECT_NAME
```

In this mode, you can specify an arbitrary corpus location for the fuzz target
(instead of the corpus downloaded from OSS-Fuzz) by using `--corpus-dir`:

```bash
$ python3 infra/helper.py coverage --fuzz-target=<fuzz_target_name> \
    --corpus-dir=<my_local_corpus_dir> $PROJECT_NAME
```

### Additional arguments for `llvm-cov` (C/C++/Rust only)

You may want to use some of the options provided by the [llvm-cov tool], like
`-ignore-filename-regex=`. You can pass these to the helper script after `--`:

```bash
$ python3 infra/helper.py coverage $PROJECT_NAME -- \
    -ignore-filename-regex=.*code/to/be/ignored/.* <other_extra_args>
```

If you want to specify particular source files or directories to show in the
report, list their paths at the end of the extra arguments sequence:

```bash
$ python3 infra/helper.py coverage zlib -- \
    <other_extra_args> /src/zlib/inftrees.c /src/zlib_uncompress_fuzzer.cc /src/zlib/zutil.c
```

If you want OSS-Fuzz to use extra arguments when generating code coverage
reports for your project, add the arguments into your `project.yaml` file as
follows:

```yaml
coverage_extra_args: -ignore-filename-regex=.*crc.* -ignore-filename-regex=.*adler.* <other_extra_args>
```

[Clang's documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
[gcloud tool]: https://docs.cloud.google.com/sdk/docs/install-sdk
[llvm-cov tool]: https://llvm.org/docs/CommandGuide/llvm-cov.html

---

### Advanced Topics Corpora (`docs/advanced-topics/corpora.md`)

---
layout: default
title: Corpora
parent: Advanced topics
nav_order: 3
permalink: /advanced-topics/corpora/
---

# Accessing Corpora
{: .no_toc}

If you want to access the corpora that we are using for your fuzz targets
(synthesized by the fuzzing engines), follow these steps.

- TOC
{:toc}
---

## Obtain access

To get access to a project's corpora, you must be listed as the
primary contact or as an auto cc in the project's `project.yaml` file, as described
in the [New Project Guide]({{ site.baseurl }}/getting-started/new-project-guide/#projectyaml).
If you don't do this, most of the links below won't work.

## Install Google Cloud SDK

The corpora for fuzz targets are stored on [Google Cloud
Storage](https://cloud.google.com/storage/). To access them, you need to
[install the gcloud
tool](https://docs.cloud.google.com/sdk/docs/install-sdk, which is part of
the Google Cloud SDK. Follow the instructions on the installation page to
login with the Google account listed in your project's `project.yaml` file.

## Viewing the corpus for a fuzz target

The fuzzer statistics page for your project on
[ClusterFuzz]({{ site.baseurl }}/further-reading/clusterfuzz)
contains a link to the Google Cloud console for your corpus under the
**corpus_size** column. Click the link to browse and download individual test inputs in the
corpus.



## Downloading the corpus 

If you want to download the entire corpus, click the link in the **corpus_size** column, then
copy the **Buckets** path at the top of the page:



Copy the corpus to a directory on your
machine by running the following command:

```bash
$ gcloud storage cp -r gs://<bucket_path> <local_directory>
```
Using the expat example above, this would be:

```bash
$ gcloud storage cp -r \
    gs://expat-corpus.clusterfuzz-external.appspot.com/libFuzzer/expat_parse_fuzzer \
    <local_directory>
```

## Corpus backups

We keep daily zipped backups of your corpora. These can be accessed from the
**corpus_backup** column of the fuzzer statistics page. Downloading these can
be significantly faster than running `gcloud storage cp -r` on the corpus bucket.

---

### Advanced Topics Debugging (`docs/advanced-topics/debugging.md`)

---
layout: default
title: Debugging
parent: Advanced topics
nav_order: 4
permalink: /advanced-topics/debugging/
---

# Debugging issues
{: .no_toc}

- TOC
{:toc}
---

## Debugging build scripts

While developing your build script, it may be useful to run bash within the
container:

```bash
$ python3 infra/helper.py shell $PROJECT_NAME  # runs /bin/bash within container
$ compile                                     # runs compilation manually
```

## Debugging fuzzers with GDB

If you wish to debug a fuzz target with gdb, you can use the base-runner-debug
image:

```bash
# Copy input testcase into host output directory so it can be accessed
# within the Docker image.
$ cp /path/to/testcase build/out/$PROJECT_NAME

# Run the Docker image containing GDB.
$ python3 infra/helper.py shell base-runner-debug
$ gdb --args /out/$PROJECT_NAME/$FUZZ_TARGET_NAME /out/$PROJECT_NAME/testcase
```

**Note:** The `base-runner-debug` image does not have access to your sources, so
you will not be able to do source code level debugging. We recommend integrating
your fuzz target upstream as part of
[ideal integration]({{ site.baseurl }}/advanced-topics/ideal-integration/)
for debugging purposes.

---

### Advanced Topics Fuzz Introspector (`docs/advanced-topics/fuzz_introspector.md`)

---
layout: default
title: Fuzz Introspector
parent: Advanced topics
nav_order: 2
permalink: /advanced-topics/fuzz-introspector/
---

# Fuzz Introspector
{: .no_toc}

For projects written in C/C++, Python and Java you can generate Fuzz
Introspector reports to help guide the development of your fuzzing suite.
These reports help to extract details about the fuzzing setup of your
project with the goal of making it easier to improve the fuzzing set up.
The Fuzz Introspector reports are generated automatically and uploaded
to the cloud like code coverage reports, and you can also generate them
locally using the OSS-Fuzz helper script.


- TOC
{:toc}
---

## Fuzz Introspector overview

As soon as your project is run with ClusterFuzz (<1 day), you can view the Fuzz
Introspector report for your project.
[Fuzz Introspector](https://github.com/ossf/fuzz-introspector) helps you
understand your fuzzers' performance and identify any potential blockers.
It provides individual and aggregated fuzzer reachability and coverage reports.
You can monitor each fuzzer's static reachability potential and compare it
against dynamic coverage and identify any potential bottlenecks.
Fuzz Introspector can offer suggestions on increasing coverage by adding new
fuzz targets or modify existing ones.
Fuzz Introspector reports can be viewed from the [OSS-Fuzz
homepage](https://oss-fuzz.com/) or through this
[index](http://oss-fuzz-introspector.storage.googleapis.com/index.html).

- [Fuzz Introspector documentation](https://fuzz-introspector.readthedocs.io/en/latest/)
- [Fuzz Introspector source code](https://github.com/ossf/fuzz-introspector)
- [OSS-Fuzz Fuzz Introspector reports](http://oss-fuzz-introspector.storage.googleapis.com/index.html)


## Tutorials and guides

The reports generated can be a lot to digest when first viewing them. The 
[Fuzz Introspector documentation](https://fuzz-introspector.readthedocs.io/en/latest/)
provides various user guides and tutorials rooted in OSS-Fuzz projects, which is
a useful reference on how to make use of the reports.

For ideas on how to use Fuzz Introspector, see [user guides](https://fuzz-introspector.readthedocs.io/en/latest/user-guides/index.html) which includes sections e.g.
- [Quickly extract overview of a given project](https://fuzz-introspector.readthedocs.io/en/latest/user-guides/quick-overview.html)
- [Get ideas for new fuzz targets](https://fuzz-introspector.readthedocs.io/en/latest/user-guides/get-ideas-for-new-targets.html)
- [Comparing introspector reports](https://fuzz-introspector.readthedocs.io/en/latest/user-guides/comparing-introspector-reports.html)

## Run Fuzz Introspector locally

To generate a Fuzz Introspector report locally use `infra/helper.py` and the
`introspector` command. Fuzz Introspector relies on code coverage to
analyze a given project, and this means we need to extract code coverage in the
Fuzz Introspector process. We can do this in two ways. First, by running the fuzzers
for a given amount of time, and, second, by generating code coverage using the public
corpus available from OSS-Fuzz.


### Generate reports by running fuzzers for X seconds

The following command will generate a Fuzz Introspector report for the `libdwarf` project
and will extract code coverage based on a corpus created from running the fuzzers for 30
seconds.

```bash
$ python3 infra/helper.py introspector libdwarf --seconds=30
```

If the above command was successful, you should see output along the lines of:

```bash
INFO:root:To browse the report, run: python3 -m http.server 8008 --directory /home/my_user/oss-fuzz/build/out/libdwarf/introspector-report/inspector and navigate to localhost:8008/fuzz_report.html in your browser
```
The above output gives you directions on how to start a simple webserver using
`python3 -m http.server`, which you can use to view the Fuzz Introspector report.

### Generate reports by using public corpora

The following command will generate a Fuzz Introspector report for the `libdwarf` project
and will extract code coverage based on the publicly available corpora. 

```bash
$ python3 infra/helper.py introspector libdwarf --public-corpora
```

Assuming the above command is successful you can view the report using `python3 -m http.server`
following the example described above.


## Differences in build tooling

There are some differences in build environment for Fuzz Introspector builds
in comparison to e.g. ASAN or code coverage builds. The reason is that
Fuzz Introspector relies on certain compile-time tools to do its analysis.
This compile time tooling differs between languages, namely:
- For C/C++, Fuzz Introspector relies on [LLVM LTO](https://llvm.org/docs/LinkTimeOptimization.html) and [LLVM Gold](https://llvm.org/docs/GoldPlugin.html)
- For Python, Fuzz Introspector relies on a modified [PyCG](https://github.com/vitsalis/PyCG)
- For Java, Fuzz Introspector relies on [Soot](https://soot-oss.github.io/soot/)

The consequence of this is your project must be compatible with these projects.
PyCG and Soot have not shown to be a blocker for many projects, however, experience
has shown that sometimes a project's build needs modification in order to compile
with LLVM LTO. The easiest way to test if your project works with LLVM is checking
whether your project can compile with the flags `-flto -fuse-ld=gold` and using
the gold linker. OSS-Fuzz automatically sets these flags and linker options when
using `infra/helper.py` to build your project with `--sanitizer=introspector`, e.g.

```bash
python3 infra/helper.py build_fuzzers --sanitizer=introspector PROJ_NAME
```

---

### Advanced Topics Ideal Integration (`docs/advanced-topics/ideal_integration.md`)

---
layout: default
title: Ideal integration
parent: Advanced topics
nav_order: 1
permalink: /advanced-topics/ideal-integration/
---

# Ideal integration with OSS-Fuzz
{: .no_toc}

OSS projects have different build and test systems. We can't expect them all to
implement and maintain fuzz targets or integrate them with OSS-Fuzz in the same
way. However, we do have recommendations.

This page documents several features (starting from the easiest) that will make
automated fuzzing simple and efficient, and will help you catch regressions
early in the development cycle. This simple
[example](https://github.com/google/oss-fuzz/tree/master/projects/example/my-api-repo)
covers most of the items. 

- TOC
{:toc}
---

## Summary

Every [fuzz target](https://llvm.org/docs/LibFuzzer.html#fuzz-target):
* Is [maintained by code owners](#fuzz-target) in their RCS (Git, SVN, etc).
* Is [built with the rest of the tests](#build-support) - no bit rot! 
* Has a [seed corpus](#seed-corpus) with good [code coverage](#coverage).
* Has a [dictionary](#dictionary), if applicable.
* Is [continuously tested on the seed corpus](#regression-testing) with
  [ASan/UBSan/MSan](https://github.com/google/sanitizers).
* Is [fast and has no OOMs](#performance).

## Fuzz Target

The code of the [fuzz target(s)](https://llvm.org/docs/LibFuzzer.html#fuzz-target) should be
part of the project's source code repository.  All fuzz targets should be easily
discoverable (reside in the same directory, follow the same naming pattern,
etc.). 

This makes it easy to maintain the fuzzers and minimizes breakages that can
arise as source code changes over time.

Make sure to fuzz the target locally for a small period of time to ensure that 
it does not crash, hang, or run out of memory instantly. Also make sure that the fuzzer can
make at least some progress. If you're having trouble, read about [what makes a good fuzz
target](https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md).

The interface between the [fuzz target](https://llvm.org/docs/LibFuzzer.html#fuzz-target)
and the fuzzing engines is C, so you can use either C or C++ to implement the
fuzz target. Make sure to not return values other than **zero** [^1].

Examples: 
[boringssl](https://github.com/google/boringssl/tree/master/fuzz),
[SQLite](https://www.sqlite.org/src/artifact/ad79e867fb504338),
[s2n](https://github.com/awslabs/s2n/tree/master/tests/fuzz),
[openssl](https://github.com/openssl/openssl/tree/master/fuzz),
[FreeType](http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/tools/ftfuzzer),
[re2](https://github.com/google/re2/tree/master/re2/fuzzing),
[harfbuzz](https://github.com/behdad/harfbuzz/tree/master/test/fuzzing),
[pcre2](https://vcs.pcre.org/pcre2/code/trunk/src/pcre2_fuzzsupport.c?view=markup),
[ffmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/tools/target_dec_fuzzer.c).

[^1]: While LibFuzzer uses a non-zero value as a signal to discard inputs other fuzzers in
use by OSS-Fuzz do not necessarily support this behavior. (Discarding inputs can be used
to stop a fuzzer from exploring further, which should only be used with good reason.)

## Build support

Many different build systems exist in the open-source world. The less OSS-Fuzz
knows about them, the better it can scale.

An ideal build integration for OSS-Fuzz looks like this:
* For every fuzz target `foo` in the project, there is a build rule that
builds `foo_fuzzer`, a binary that: 
	* Contains the fuzzing entry point.
	* Contains (`LLVMFuzzerTestOneInput`) and all the code it depends on.
	* Uses the `main()` function from `$LIB_FUZZING_ENGINE` (env var [provided]({{ site.baseurl }}/getting-started/new-project-guide/) by OSS-Fuzz environment).
* Since the build system supports changing the compiler and passing extra compiler
flags, the build command for `foo_fuzzer` looks similar to this:

```bash
# Assume the following env vars are set:
# CC, CXX, CFLAGS, CXXFLAGS, LIB_FUZZING_ENGINE
$ make_or_whatever_other_command foo_fuzzer
```

This minimizes OSS-Fuzz-specific configuration, making your fuzzing more robust.

There is no point in hardcoding the exact compiler flags in the build system
because they a) may change and b) depend on the fuzzing engine and sanitizer
being used.

## Seed Corpus

The *seed corpus* is a set of test inputs, stored as individual files, provided
to the fuzz target as a starting point (to "seed" the mutations). The quality of
the seed corpus has a huge impact on fuzzing efficiency; the higher the quality,
the easier it is for the fuzzer to discover new code paths. The ideal corpus is
a minimal set of inputs that provides maximal code coverage. 

For better OSS-Fuzz integration,  the seed corpus should be available in
revision control (it can be the same as or different from the source code). It
should be regularly extended with the inputs that (used to) trigger bugs and/or
touch new parts of the code. 

Examples: 
[boringssl](https://github.com/google/boringssl/tree/master/fuzz),
[openssl](https://github.com/openssl/openssl/tree/master/fuzz),
[nss](https://github.com/mozilla/nss-fuzzing-corpus) (corpus in a separate repo).

## Dictionary

For some input types, a simple dictionary of tokens used by the input language
can have a dramatic impact on fuzzing efficiency.  For example, when fuzzing an
XML parser, a dictionary of XML tokens is helpful. AFL++ has a
[collection](https://github.com/AFLplusplus/AFLplusplus/tree/master/dictionaries)
of dictionaries for popular data formats. Ideally, a dictionary should be
maintained alongside the fuzz target, and it must use [correct
syntax](https://llvm.org/docs/LibFuzzer.html#dictionaries).

## Coverage

For a fuzz target to be useful, it must have good coverage in the code that it
is testing. You can view the coverage for your fuzz targets by looking at the
[fuzzer stats]({{ site.baseurl }}/further-reading/clusterfuzz#fuzzer-stats)
dashboard on ClusterFuzz, as well as [coverage reports]({{ site.baseurl
}}/further-reading/clusterfuzz#coverage-reports).

To generate an aggregated code coverage report for your project, please see the
[code coverage]({{ site.baseurl }}/advanced-topics/code-coverage) page.

Coverage can often be improved by adding dictionaries, more inputs for seed
corpora, and fixing timeouts/out-of-memory bugs in your targets.

## Regression Testing

Fuzz targets should be regularly tested (not necessarily fuzzed!) as a part of
the project's regression testing process. One way to do so is to link the fuzz
target with a simple standalone driver
([example](https://github.com/llvm-mirror/compiler-rt/tree/master/lib/fuzzer/standalone))
that runs the provided inputs, then use this driver with the seed corpus created
in previous step. We recommend you use
[sanitizers](https://github.com/google/sanitizers) during regression testing.

Examples: [SQLite](https://www.sqlite.org/src/artifact/d9f1a6f43e7bab45),
[openssl](https://github.com/openssl/openssl/blob/master/fuzz/test-corpus.c).

## Performance

Fuzz targets should perform well, because high memory usage and/or slow
execution speed can slow the down the growth of coverage and finding of new
bugs. ClusterFuzz provides a [performance analyzer]({{ site.baseurl
}}/further-reading/clusterfuzz/#performance-analyzer) for each fuzz target that
shows problems that are impacting performance.

## Not a project member?

If you are a member of the project you want to fuzz, most of the steps above are
simple. However in some cases, someone outside the project team may want to fuzz
the code, and the project maintainers are not interested in helping.

In such cases, we can host the fuzz targets, dictionaries, etc. in OSS-Fuzz's 
repository and mention them in the Dockerfile. It's not ideal, because the fuzz
targets will not be continuously tested, so may quickly bitrot.

Examples: [libxml2](https://github.com/google/oss-fuzz/tree/master/projects/libxml2),
[c-ares](https://github.com/google/oss-fuzz/tree/master/projects/c-ares), [expat](https://github.com/google/oss-fuzz/tree/master/projects/expat).

If you are not a project maintainer, we may not be able to CC you to security
bugs found by OSS-Fuzz.

---

### Advanced Topics Reproducing (`docs/advanced-topics/reproducing.md`)

---
layout: default
title: Reproducing
parent: Advanced topics
nav_order: 5
permalink: /advanced-topics/reproducing/
---

# Reproducing OSS-Fuzz issues
{: .no_toc}

You've been CCed on an OSS-Fuzz issue
([examples](https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&q=Type%3ABug%2CBug-Security)).
Now what? Before attempting to fix the bug, you should be able to reliably
reproduce it. 

- TOC
{:toc}
---

## Fuzz target bugs

Every issue has a [reproducer file]({{ site.baseurl
}}/reference/glossary/#reproducer) (also know as a "testcase" file) attached.
Download it. This file contains the bytes that were fed to the [fuzz
target](https://llvm.org/docs/LibFuzzer.html#fuzz-target).

**Note:** If the issue is not public, you will need to login using a
[Google account](https://support.google.com/accounts/answer/176347?hl=en)
([why?]({{ site.baseurl
}}/faq/#why-do-you-require-a-google-account-for-authentication)) that the bug
report CCs.

If you have already
[integrated]({{ site.baseurl }}/advanced-topics/ideal-integration/)
the fuzz target with your build and test system, all you have to do is run this command:
```bash
$ ./fuzz_target_binary <testcase_path>
```

For timeout bugs, add the `-timeout=65` argument. For OOM bugs, add the
`-rss_limit_mb=2560` argument. Read more on [how timeouts and OOMs are
handled]({{ site.baseurl }}/faq/#how-do-you-handle-timeouts-and-ooms).

Depending on the nature of the bug, the fuzz target binary needs to be built
with the appropriate [sanitizer](https://github.com/google/sanitizers)
(for example, if it's a buffer overflow, build with
[AddressSanitizer](http://clang.llvm.org/docs/AddressSanitizer.html)).

If you're not sure how to build the fuzzer using the project's build system,
you can also use Docker commands to replicate the exact build steps used by
OSS-Fuzz, then feed the reproducer input to the fuzz target ([how?]({{
site.baseurl }}/getting-started/new-project-guide/#prerequisites), [why?]({{
site.baseurl }}/faq/#why-do-you-use-docker)).

## Building using Docker

### Cloning OSS-Fuzz

To use the following `infra/helper.py` commands, you need a checkout of OSS-Fuzz:

```bash
$ git clone --depth=1 https://github.com/google/oss-fuzz.git
$ cd oss-fuzz
```

### Pull the latest Docker images

Docker images get regularly updated with a newer version of build tools, build
configurations, scripts, and other changes. In some cases, a particular issue
can be reproduced only with a fresh image being used. Pull the latest images
by running the following command:

```bash
$ python3 infra/helper.py pull_images
```

### Build the image and the fuzzers

Run the following commands:

```bash
$ python3 infra/helper.py build_image $PROJECT_NAME
$ python3 infra/helper.py build_fuzzers --sanitizer <address/memory/undefined> \
    --architecture <x86_64/i386> $PROJECT_NAME
```

The `sanitizer` used in the report is the value in the
**Sanitizer** column. It's one of the following:
  * **address** for AddressSanitizer.
  * **memory** for MemorySanitizer.
  * **undefined** for UndefinedBehaviorSanitizer.

**Notes**:
   * The `architecture` argument is only necessary if you want to specify
`i386` configuration.
   * Some bugs (specially ones related to pointer and integer overflows) are reproducible only in 32 bit mode or only in 64 bit mode.
If you can't reproduce a particular bug building for x86_64, try building for i386.

## Reproducing bugs

After you build an image and a fuzzer, you can reproduce a bug by running the following command:

```bash
$ python3 infra/helper.py reproduce $PROJECT_NAME <fuzz_target_name> <testcase_path>
```

For example, to build the [libxml2](https://github.com/google/oss-fuzz/tree/master/projects/libxml2)
project with UndefinedBehaviorSanitizer (`undefined`) instrumentation and
reproduce a crash testcase for a fuzzer named `libxml2_xml_read_memory_fuzzer`,
you would run: 

```bash
$ python3 infra/helper.py build_image libxml2
$ python3 infra/helper.py build_fuzzers --sanitizer undefined libxml2
$ python3 infra/helper.py reproduce libxml2 libxml2_xml_read_memory_fuzzer ~/Downloads/testcase
```

## Reproduce using local source checkout

You can also build fuzzers from a local source checkout by using these
commands:

```bash
$ python3 infra/helper.py build_fuzzers \
    --sanitizer <address/memory/undefined> $PROJECT_NAME <source_path>
$ python3 infra/helper.py reproduce $PROJECT_NAME <fuzz_target_name> <testcase_path>
```

Once you reproduce the bug, you can do the following:

- **Fix issue:** Write a patch to fix the issue in your local checkout, then
   use the previous command to verify the fix (i.e. no crash occurred). 
   [Use gdb]({{ site.baseurl }}/advanced-topics/debugging/#debugging-fuzzers-with-gdb)
   if needed.
- **Submit fix:** Submit the fix in the project's repository. ClusterFuzz will
  automatically pick up the changes, recheck the testcase, and close the
  issue (in &lt; 1 day).
- **Improve fuzzing support:** Consider
   [improving your integration with OSS-Fuzz]({{ site.baseurl }}/advanced-topics/ideal-integration/).

## Reproducing build failures

Our infrastructure runs some sanity tests to make sure that your build was
correctly configured, even if it succeeded. To reproduce these locally, run these commands:

```bash
$ python3 infra/helper.py build_image $PROJECT_NAME
$ python3 infra/helper.py build_fuzzers --sanitizer <address/memory/undefined> \
    --engine <libfuzzer/afl/honggfuzz/centipede> --architecture <x86_64/i386> $PROJECT_NAME
$ python3 infra/helper.py check_build  --sanitizer <address/memory/undefined> \
    --engine <libfuzzer/afl/honggfuzz/centipede> --architecture <x86_64/i386> $PROJECT_NAME \
    <fuzz_target_name>
```

**Note:** Unless you have a reason to think the build is an `i386` build, the build
is probably an `x86_64` build and the `architecture` argument can be omitted.

If you need to reproduce a `coverage` build failure, follow the
[Code Coverage page]({{ site.baseurl }}/advanced-topics/code-coverage) to build
your project and generate a code coverage report.

---

### Further Reading Clusterfuzz (`docs/further-reading/clusterfuzz.md`)

---
layout: default
title: ClusterFuzz
parent: Further reading
nav_order: 1
permalink: /further-reading/clusterfuzz/
---

# ClusterFuzz

[ClusterFuzz](https://github.com/google/clusterfuzz) is the distributed fuzzing
infrastructure behind OSS-Fuzz. It was initially built for fuzzing Chrome at
scale.

- TOC
{:toc}
---

## Web interface

ClusterFuzz provides a [web interface](https://oss-fuzz.com)
to view statistics about your fuzz targets, as well as current crashes.

*Note*: Access is restricted to project developers who we auto CC on new bug
reports.

## Testcase reports

ClusterFuzz will automatically de-duplicate and file reproducible crashes into
our [bug tracker](https://bugs.chromium.org/p/oss-fuzz/issues/list). We provide
a crash report page that gives you the stack trace, a link to the crashing
testcase, and regression ranges where the bug was most likely introduced.



## Fuzzer stats

You can view statistics about your fuzz targets (e.g. speed, coverage
information, memory usage) on our fuzzer statistics dashboard.





## Coverage reports

We provide coverage reports, where we highlight the parts of source code that
are being reached by your fuzz target. Make sure to look at the uncovered code
marked in red and add appropriate fuzz targets to cover those use cases.




## Performance analyzer

You can view performance issues that your fuzz target is running into (e.g.
leaks, timeouts, etc) by clicking on `Performance` link on our fuzzer statistics
dashboard. Make sure to fix all cited issues, so as to keep your fuzz target
running efficiently and finding new bugs.



## Crash stats

You can view statistics of crashes over time on our crash statistics dashboard.

---

### Further Reading Further Reading (`docs/further-reading/further_reading.md`)

---
layout: default
title: Further reading
has_children: true
nav_order: 5
permalink: /further-reading/
---

# Further reading

---

### Further Reading Fuzzer Environment (`docs/further-reading/fuzzer_environment.md`)

---
layout: default
title: Fuzzer environment
parent: Further reading
nav_order: 2
permalink: /further-reading/fuzzer-environment/
---

# Fuzzer environment on ClusterFuzz

Your fuzz targets will be run on a
[Google Compute Engine](https://cloud.google.com/compute/) VM (Linux).

- TOC
{:toc}
---

## Runtime Dependencies

You should not make any assumptions on the availability of dependent packages 
in the execution environment. Packages that are installed via
[Dockerfile]({{ site.baseurl }}/getting-started/new-project-guide/#dockerfile)
or built as part of 
[build.sh]({{ site.baseurl }}/getting-started/new-project-guide/#buildsh)
are not available on the bot runtime environment (where the fuzz targets run).

If you need these dependencies in the runtime environment, you can either:

- (recommended) Build the dependencies statically in
[build.sh]({{ site.baseurl }}/getting-started/new-project-guide/#buildsh)
([example](https://github.com/google/oss-fuzz/blob/64f8b6593da141b97c98c7bc6f07df92c42ee010/projects/ffmpeg/build.sh#L26)).
Their source code should be inside the `$SRC` directory so that coverage can find it.

- Or install the packages via Dockerfile
([example](https://github.com/google/oss-fuzz/blob/2d5e2ef84f281e6ab789055aa735606d3122fda9/projects/tor/Dockerfile#L19))
and then link statically against them
([example](https://github.com/google/oss-fuzz/blob/2d5e2ef84f281e6ab789055aa735606d3122fda9/projects/tor/build.sh#L40)).
**Dependencies built in this way will not be instrumented** and may prevent
the fuzzer from finding bugs if they are involved in the execution of a fuzz target.

All build artifacts needed during fuzz target execution should be inside the
`$OUT` directory. Only those artifacts are archived and used on the bots.
Everything else is ignored (e.g. artifacts in `$WORK`, `$SRC`, etc) and hence
is not available in the execution environment.

We strongly recommend static linking because it just works. 
However dynamic linking can work if shared objects are included in the `$OUT` directory and are loaded relative
to `'$ORIGIN'`, the path of the binary (see the discussion of `'$ORIGIN'` [here](http://man7.org/linux/man-pages/man8/ld.so.8.html)).
A fuzzer can be instructed to load libraries relative to `'$ORIGIN'` during compilation (i.e. `-Wl,-rpath,'$ORIGIN/lib'` )
or afterwards using `chrpath -r '$ORIGIN/lib' $OUT/$fuzzerName` ([example](https://github.com/google/oss-fuzz/blob/09aa9ac556f97bd4e31928747eca0c8fed42509f/projects/php/build.sh#L40)). Note that `'$ORIGIN'` should be surrounded
by single quotes because it is not an environment variable like `$OUT` that can be retrieved during execution of `build.sh`.
Its value is retrieved during execution of the binary. You can verify that you did this correctly using `ldd <fuzz_target_name>` and the `check_build` command in `infra/helper.py`.

You should ensure that the fuzz target works correctly by using `run_fuzzer`
command (see instructions
[here]({{ site.baseurl }}/getting-started/new-project-guide/#testing-locally)).
This command uses a clean base-runner docker container and not the base-builder
docker container created during build-time.

## argv[0]

You must not modify `argv[0]`. It is required for certain things to work
correctly.

## Current working directory

You should not make any assumptions about the current working directory of your
fuzz target. If you need to load data files, please use `argv[0]` to get the
directory where your fuzz target executable is located.

## File system

Everything except `/tmp` is read-only, including the directory that your fuzz
target executable lives in.

`/dev` is also unavailable.

## Hardware

Your project should not be compiled with `-march=native` or `-mtune=native`
flags, as the build infrastructure and fuzzing machines may have different CPUs
as well as other hardware differences. You may however use `-mtune=generic`.

---

### Getting Started Accepting New Projects (`docs/getting-started/accepting_new_projects.md`)

---
layout: default
title: Accepting new projects
parent: Getting started
nav_order: 1
permalink: /getting-started/accepting-new-projects/
---

# Accepting New Projects

To be accepted to OSS-Fuzz, an open-source project must
have a significant user base and/or be critical to the global IT infrastructure.

To submit a new project, do the following:

1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/)
with a new `projects/<project_name>/project.yaml` file
([example](https://github.com/google/oss-fuzz/tree/master/projects/libarchive/project.yaml)).
    **Note:** `project_name` can only contain alphanumeric characters,
    underscores(_) or dashes(-).
2. In the file, provide the following information:
  * Your project's homepage. ([`homepage`]({{ site.baseurl }}/getting-started/new-project-guide/#homepage))
  * Your project's main repository URL. ([`main_repo`]({{ site.baseurl }}/getting-started/new-project-guide/#main_repo))
  * Your project's primary language. ([`language`]({{ site.baseurl }}/getting-started/new-project-guide/#language))
  * An email address for the engineering contact to be CCed on new issues ([`primary_contact`]({{ site.baseurl }}/getting-started/new-project-guide/#primary)), satisfying the following:
       * The address belongs to an established project committer (according to VCS logs).
        If the address isn't you, or if the address differs from VCS, we'll require an informal
        email verification.
       * The address is associated with a Google account
        ([why?]({{ site.baseurl }}/faq/#why-do-you-require-a-google-account-for-authentication)).
        If you use an alternate email address
        [linked to a Google Account](https://support.google.com/accounts/answer/176347?hl=en),
        you'll only get access to [filed bugs in the issue tracker](https://bugs.chromium.org/p/oss-fuzz/issues/list), not to the [ClusterFuzz]({{ site.baseurl }}/further-reading/clusterfuzz)
        dashboard. This is due to appengine API limitations.
3. Once your project is accepted, configure it by following the
  [New Project Guide]({{ site.baseurl }}/getting-started/new-project-guide/).

---

### Getting Started Bug Disclosure Guidelines (`docs/getting-started/bug_disclosure_guidelines.md`)

---
layout: default
title: Bug disclosure guidelines
parent: Getting started
nav_order: 3
permalink: /getting-started/bug-disclosure-guidelines/
---

## Bug Disclosure Guidelines

Following [Google's standard disclosure policy](https://googleprojectzero.blogspot.com/2015/02/feedback-and-data-driven-updates-to.html),
OSS-Fuzz will adhere to following disclosure principles:

  - **Deadline**. After notifying project authors, we will open reported
    issues to the public in 90 days, or after the fix is released (whichever
    comes earlier).
  - **Weekends and holidays**. If a deadline is due to expire on a weekend,
    the deadline will be moved to the next normal work day.
  - **Grace period**. We have a 14-day grace period. If a 90-day deadline
    expires but the upstream engineers let us know before the deadline that a
    patch is scheduled for release on a specific day within 14 days following
    the deadline, the public disclosure will be delayed until the availability
    of the patch.

---

### Getting Started Continuous Integration (`docs/getting-started/continuous_integration.md`)

---
layout: default
title: Continuous Integration
parent: Getting started
nav_order: 4
permalink: /getting-started/continuous-integration/
---

# Continuous Integration

OSS-Fuzz offers **CIFuzz**, a GitHub action/CI job that runs your fuzz targets
on pull requests. This works similarly to running unit tests in CI. CIFuzz helps
you find and fix bugs before they make it into your codebase.
Currently, CIFuzz primarily supports projects hosted on GitHub.
Non-OSS-Fuzz users can use CIFuzz with additional features through
[ClusterFuzzLite](https://google.github.io/clusterfuzzlite/).

## How it works

CIFuzz builds your project's fuzzers from the source at a particular
pull request or commit. Then CIFuzz runs the fuzzers for a short amount of time.
If CIFuzz finds a crash, CIFuzz reports the stacktrace, makes the crashing
input available for download and the CI test fails (red X).

If CIFuzz doesn't find a crash during the allotted time, the CI test passes
(green check). If CIFuzz finds a crash, it reports the crash only if both of
following are true:
* The crash is reproducible (on the PR/commit build).
* The crash does not occur on older OSS-Fuzz builds. (If the crash does occur
  on older builds, then it was not introduced by the PR/commit
  being tested.)

If your project supports [OSS-Fuzz's code coverage]({{ site.baseurl }}/advanced-topics/code-coverage),
CIFuzz only runs the fuzzers affected by a pull request/commit.
Otherwise it will divide up the allotted fuzzing time (10 minutes by default)
among all fuzzers in the project.

CIFuzz uses 30 day old/public regressions and corpora from OSS-Fuzz. This makes
fuzzing more effective and gives you regression testing for free.

## Requirements

1. Your project must be integrated with OSS-Fuzz.
1. Your project is hosted on GitHub.
1. Your repository needs to be cloned with `git` in oss-fuzz Dockerfile (do not use `go get` or other methods)

## Integrating into your repository

You can integrate CIFuzz into your project using the following steps:
1. Create a `.github` directory in the root of your project.
1. Create a `workflows` directory inside of your `.github` directory.
1. Copy the example [`cifuzz.yml`](https://github.com/google/oss-fuzz/blob/master/infra/cifuzz/example_cifuzz.yml)
file over from the OSS-Fuzz repository to the `workflows` directory.
1. Change the `oss-fuzz-project-name` value in `cifuzz.yml` from `example` to the name of your OSS-Fuzz project. It is **very important** that you use your OSS-Fuzz project name which is case sensitive. This name
is the name of your project's subdirectory in the [`projects`](https://github.com/google/oss-fuzz/tree/master/projects) directory of OSS-Fuzz.
1. Set the value of `fuzz-seconds`. The longest time that the project maintainers are acceptable with should be used. This value should be at minimum 600 seconds and scale with project size.

Your directory structure should look like the following:
```
project
|___ .github
|    |____ workflows
|          |____ cifuzz.yml
|___ other-files
```

cifuzz.yml for an example project:

```yaml
name: CIFuzz
on: [pull_request]
permissions: {}
jobs:
 Fuzzing:
   runs-on: ubuntu-latest
   permissions:
     security-events: write
   steps:
   - name: Build Fuzzers
     id: build
     uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
   - name: Run Fuzzers
     uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
       fuzz-seconds: 600
       output-sarif: true
   - name: Upload Crash
     uses: actions/upload-artifact@v4
     if: failure() && steps.build.outcome == 'success'
     with:
       name: artifacts
       path: ./out/artifacts
   - name: Upload Sarif
     if: always() && steps.build.outcome == 'success'
     uses: github/codeql-action/upload-sarif@v2
     with:
      # Path to SARIF file relative to the root of the repository
      sarif_file: cifuzz-sarif/results.sarif
      checkout_path: cifuzz-sarif
```


### Optional configuration

#### Configurable Variables

`language`: (optional) The language your target program is written in. Defaults
to `c++`. This should be the same as the value you set in `project.yaml`. See
[this explanation]({{ site.baseurl }}//getting-started/new-project-guide/#language)
for more details.

`fuzz-seconds`: Determines how long CIFuzz spends fuzzing your project in seconds.
The default is 600 seconds. The GitHub Actions max run time is 21600 seconds (6
hours). This variable is only meaningful when supplied to the `run_fuzzers`
action, not the `build_fuzzers` action.

`dry-run`: Determines if CIFuzz surfaces errors. The default value is `false`. When set to `true`,
CIFuzz will never report a failure even if it finds a crash in your project.
This requires the user to manually check the logs for detected bugs. If dry run mode is desired,
make sure to set the dry-run parameters in both the `Build Fuzzers` and `Run Fuzzers` action step.

`allowed-broken-targets-percentage`: Can be set if you want to set a stricter
limit for broken fuzz targets than OSS-Fuzz's check_build. Most users should
not set this. This value is only meaningful when supplied to the `run_fuzzers`
action, not the `build_fuzzers` action.

`sanitizer`: Determines a sanitizer to build and run fuzz targets with. The choices are `'address'`,
`'memory'` and `'undefined'`. The default is `'address'`. It is important to note that the `Build Fuzzers`
and the `Run Fuzzers` sanitizer field needs to be the same. To specify a list of sanitizers
a [matrix](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix)
can be used. To use a sanitizer add it to the list of sanitizers in the matrix field below:

`report-timeouts`: Determines whether to report fails due to timeouts.

`report-ooms`: Determines whether to report fails due to OOM.

```yaml
{% raw %}
name: CIFuzz
on: [pull_request]
permissions: {}
jobs:
 Fuzzing:
   runs-on: ubuntu-latest
   permissions:
     security-events: write
   strategy:
     fail-fast: false
     matrix:
       sanitizer: [address, undefined, memory]
   steps:
   - name: Build Fuzzers (${{ matrix.sanitizer }})
     id: build
     uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
       sanitizer: ${{ matrix.sanitizer }}
   - name: Run Fuzzers (${{ matrix.sanitizer }})
     uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
       fuzz-seconds: 600
       sanitizer: ${{ matrix.sanitizer }}
       output-sarif: true
   - name: Upload Crash
     uses: actions/upload-artifact@v4
     if: steps.build.outcome == 'success'
     with:
       name: ${{ matrix.sanitizer }}-artifacts
       path: ./out/artifacts
   - name: Upload Sarif
    if: always() && steps.build.outcome == 'success'
    uses: github/codeql-action/upload-sarif@v2
    with:
      # Path to SARIF file relative to the root of the repository
      sarif_file: cifuzz-sarif/results.sarif
      checkout_path: cifuzz-sarif
{% endraw %}
```

#### Branches and paths

You can make CIFuzz trigger only on certain branches or paths by following the
instructions [here](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions).
For example, the following code can used to trigger CIFuzz only on changes to
C/C++ code residing on master and release branches:

```yaml
name: CIFuzz
on:
  pull_request:
    branches:
      - master
      - 'releases/**'
    paths:
      - '**.c'
      - '**.cc'
      - '**.cpp'
      - '**.cxx'
      - '**.h'
permissions: {}
jobs:
 Fuzzing:
   runs-on: ubuntu-latest
   steps:
   - name: Build Fuzzers
     id: build
     uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
   - name: Run Fuzzers
     uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
     with:
       oss-fuzz-project-name: 'example'
       language: c++
       fuzz-seconds: 600
   - name: Upload Crash
     uses: actions/upload-artifact@v4
     if: failure() && steps.build.outcome == 'success'
     with:
       name: artifacts
       path: ./out/artifacts
```

You can checkout CIFuzz configs for OSS-Fuzz projects. Example -
[systemd](https://github.com/systemd/systemd/blob/main/.github/workflows/cifuzz.yml),
[curl](https://github.com/curl/curl/blob/master/.github/workflows/fuzz.yml).

## Ubuntu 24.04 Support

CIFuzz supports building and running fuzzers in an Ubuntu 24.04 environment.
Existing projects will continue to use the legacy environment (Ubuntu 20.04) by default,
preserving current behavior.

To migrate your project to Ubuntu 24.04, add the following line to your `project.yaml`:

```yaml
base_os_version: ubuntu-24-04
```

For OSS-Fuzz projects, this file is located at `projects/<project_name>/project.yaml`.
For external projects (ClusterFuzzLite), this file is typically located at `.clusterfuzzlite/project.yaml`.

## Understanding results

The results of CIFuzz can be found in two different places.

* Run fuzzers log:
    1. This log can be accessed in the `actions` tab of a CIFuzz integrated repo.
    1. Click on the `CIFuzz` button in the workflow selector on the left hand side.
    1. Click on the event triggered by your desired pull request.
    1. Click the `Fuzzing` workflow.
    1. Select the `Run Fuzzer` drop down. It should show the timestamps and results
    from each of the fuzz targets.





*  Artifacts:
When the fuzzer crashes the input file that causes the crash is uploaded as an
artifact.
To download the artifact, do the following steps:
1. Click on the summary from the run, as illustrated in the screenshot below:



2. Click on the artifact you wish to download from the summary page, as
   illustrated in the screenshot below:



## Feedback/Questions/Issues

Create an issue in [OSS-Fuzz](https://github.com/google/oss-fuzz/issues/new) if you have questions or any other feedback on CIFuzz.

---

### Getting Started Getting Started (`docs/getting-started/getting_started.md`)

---
layout: default
title: Getting started
has_children: true
nav_order: 2
permalink: /getting-started/
---

# Getting started
These pages walk you through the process of integrating your open source project
with OSS-Fuzz.

---

### Getting Started New Project Guide (`docs/getting-started/new_project_guide.md`)

---
layout: default
title: Setting up a new project
parent: Getting started
has_children: true
nav_order: 2
permalink: /getting-started/new-project-guide/
---

# Setting up a new project
{: .no_toc}

- TOC
{:toc}
---

## Prerequisites

Before you can start setting up your new project for fuzzing, you must do the following:

- [Integrate]({{ site.baseurl }}/advanced-topics/ideal-integration/) one or more [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target)
  with the project you want to fuzz.

  For examples, see
[boringssl](https://github.com/google/boringssl/tree/master/fuzz) or
[SQLite](https://www.sqlite.org/src/artifact/ad79e867fb504338) (C/C++),
[go-fuzz](https://github.com/dvyukov/go-fuzz-corpus/tree/86a5af9d6842f80b205a082538ea28f61bbb8ccb) or
[syzkaller](https://github.com/google/syzkaller/tree/7c7ded697e6322b0975f061b7e268fe44f585dab/prog/test)
(Go).

- [Install Docker](https://docs.docker.com/engine/installation)
  (Googlers can visit [go/installdocker](https://goto.google.com/installdocker)).
  [Why Docker?]({{ site.baseurl }}/faq/#why-do-you-use-docker)

  If you want to run `docker` without `sudo`, you can
  [create a docker group](https://docs.docker.com/engine/installation/linux/ubuntulinux/#/create-a-docker-group).

  **Note:** Docker images can consume significant disk space. Run
  [docker-cleanup](https://gist.github.com/mikea/d23a839cba68778d94e0302e8a2c200f)
  periodically to garbage-collect unused images.

- (optional) [Install gsutil](https://cloud.google.com/storage/docs/gsutil_install) for local code coverage testing.
  For Google internal (gLinux) machines, please refer [here](https://cloud.google.com/storage/docs/gsutil_install#deb) instead.

## Creating the file structure

Each OSS-Fuzz project has a subdirectory
inside the [`projects/`](https://github.com/google/oss-fuzz/tree/master/projects) directory in the [OSS-Fuzz repository](https://github.com/google/oss-fuzz). For example, the [boringssl](https://github.com/google/boringssl)
project is located in [`projects/boringssl`](https://github.com/google/oss-fuzz/tree/master/projects/boringssl).

Each project directory also contains the following three configuration files:

* [project.yaml](#projectyaml) - provides metadata about the project.
* [Dockerfile](#dockerfile) - defines the container environment with information
on dependencies needed to build the project and its [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target).
* [build.sh](#buildsh) - defines the build script that executes inside the Docker container and
generates the project build.

You can automatically create a new directory for your project in OSS-Fuzz and
generate templated versions of the configuration files
by running the following commands:

```bash
$ cd /path/to/oss-fuzz
$ export PROJECT_NAME=<project_name>
$ export LANGUAGE=<project_language>
$ python3 infra/helper.py generate $PROJECT_NAME --language=$LANGUAGE
```

Once the template configuration files are created, you can modify them to fit your project.

**Note:** We prefer that you keep and maintain [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) in your own source code repository. If this isn't possible, you can store them inside the OSS-Fuzz project directory you created.

## project.yaml {#projectyaml}

This configuration file stores project metadata. The following attributes are supported:

- [homepage](#homepage)
- [language](#language)
- [primary_contact](#primary)
- [auto_ccs](#auto_ccs)
- [main_repo](#main_repo)
- [vendor_ccs](#vendor) (optional)
- [sanitizers](#sanitizers) (optional)
- [architectures](#architectures) (optional)
- [help_url](#help_url) (optional)
- [builds_per_day](#build_frequency) (optional)
- [file_github_issue](#file_github_issue) (optional)
- [disable_remediation](#disable_remediation) (optional)
- [disable_remediation_pre_review](#disable_remediation_pre_review) (optional)

### homepage
You project's homepage.

### language

Programming language the project is written in. Values you can specify include:

* `c`
* `c++`
* [`go`]({{ site.baseurl }}//getting-started/new-project-guide/go-lang/)
* [`rust`]({{ site.baseurl }}//getting-started/new-project-guide/rust-lang/)
* [`python`]({{ site.baseurl }}//getting-started/new-project-guide/python-lang/)
* [`jvm` (Java, Kotlin, Scala and other JVM-based languages)]({{ site.baseurl }}//getting-started/new-project-guide/jvm-lang/)
* [`swift`]({{ site.baseurl }}//getting-started/new-project-guide/swift-lang/)
* [`javascript`]({{ site.baseurl }}//getting-started/new-project-guide/javascript-lang/)
* [`lua`]({{ site.baseurl }}//getting-started/new-project-guide/lua-lang/)

### primary_contact, auto_ccs {#primary}
The primary contact and list of other contacts to be CCed. Each person listed gets access to ClusterFuzz, including crash reports and fuzzer statistics, and are auto-cced on new bugs filed in the OSS-Fuzz
tracker. If you're a primary or a CC, you'll need to use a [Google account](https://support.google.com/accounts/answer/176347?hl=en) to get full access. ([why?]({{ site.baseurl }}/faq/#why-do-you-require-a-google-account-for-authentication)).

### main_repo {#main_repo}
Path to source code repository hosting the code, e.g. `https://path/to/main/repo.git`. 

### vendor_ccs (optional) {#vendor}
The list of vendor email addresses that are downstream consumers of the project and want access to
the bug reports as they are filed.

Any changes to this list must follow these rules:
- Approved by the project maintainer (e.g. comment on pull request, reply on project mailing list).
- An organization email address is used.

### sanitizers (optional) {#sanitizers}
The list of sanitizers to use. Possible values are: `address`, `memory` and `undefined`.
If you don't specify a list, `sanitizers` uses a default list of supported
sanitizers (currently ["address"](https://clang.llvm.org/docs/AddressSanitizer.html) and
["undefined"](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)).

[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html) ("memory") is also supported
and recommended, but is not enabled by default due to the likelihood of false positives from
un-instrumented system dependencies.
If you want to use "memory," please build all libraries your project needs using
MemorySanitizer.
This can be done by building them with the compiler flags provided during
MemorySanitizer builds.
Then, you can opt in by adding "memory" to your list of sanitizers.

If your project does not build with a particular sanitizer configuration and you need some time to fix
it, you can use `sanitizers` to override the defaults temporarily. For example, to disable the
UndefinedBehaviourSanitizer build, just specify all supported sanitizers except "undefined".

If you want to test a particular sanitizer to see what crashes it generates without filing
them in the issue tracker, you can set an `experimental` flag. For example, if you want to test "memory", set `experimental: True` like this:

```
sanitizers:
 - address
 - memory:
    experimental: True
 - undefined
 ```

Crashes can be accessed on the [ClusterFuzz
homepage]({{ site.baseurl }}/further-reading/clusterfuzz#web-interface).

`sanitizers` example: [boringssl](https://github.com/google/oss-fuzz/blob/master/projects/boringssl/project.yaml).

### architectures (optional) {#architectures}
The list of architectures to fuzz on.
ClusterFuzz supports fuzzing on x86_64 (aka x64) by default.
Some projects can benefit from i386 fuzzing. OSS-Fuzz will build and run
AddressSanitizer with libFuzzer on i386 by doing the following:

```yaml
architectures:
 - x86_64
 - i386
 ```

By fuzzing on i386 you might find bugs that:
* Only occur in architecture-specific source code (e.g. code that contains i386 assembly).
* Exist in architecture-independent source code and which only affects i386 users.
* Exist in architecture-independent source code and which affects users on other 32-bit platforms such as AArch32 (aka 32-bit ARM).

Note that some bugs which affect x86_64 may be discovered on i386 and filed as such.
On the testcase page of each oss-fuzz issue is a list of other jobs where the crash reproduces, this can let you know if the crash exists on x86_64 as well.

Fuzzing on i386 is not enabled by default because many projects won't build for i386 without some modification to their OSS-Fuzz build process.
For example, you will need to link against `$LIB_FUZZING_ENGINE` and possibly install i386 dependencies within the x86_64 docker image ([for example](https://github.com/google/oss-fuzz/blob/5b8dcb5d942b3b8bc173b823fb9ddbdca7ec6c99/projects/gdal/build.sh#L18)) to get things working.

There are [known bugs](https://github.com/google/oss-fuzz/issues/2746) in ASAN
on i386 that cause ClusterFuzz to report unreproducible crashes for 0 length
testcases. There are no plans to fix these bugs so be ready for slightly more
false positives if you use i386. These false positives should be somewhat easy
to identify since they will manifest as crashes in ASAN rather than your code.

### fuzzing_engines (optional) {#fuzzing_engines}
The list of fuzzing engines to use.
By default, `libfuzzer`, `afl`, `honggfuzz`, and `centipede` are used. It is recommended to
use all of them if possible. `libfuzzer` is required by OSS-Fuzz.

### help_url (optional) {#help_url}
A link to a custom help URL that appears in bug reports instead of the default
[OSS-Fuzz guide to reproducing crashes]({{ site.baseurl }}/advanced-topics/reproducing/). This can be useful if you assign
bugs to members of your project unfamiliar with OSS-Fuzz, or if they should follow a different workflow for
reproducing and fixing bugs than the standard one outlined in the reproducing guide.

`help_url` example: [skia](https://github.com/google/oss-fuzz/blob/master/projects/skia/project.yaml).

### builds_per_day (optional) {#build_frequency}
The number of times the project should be built per day.
OSS-Fuzz allows upto 4 builds per day, and builds once per day by default.
Example:
```yaml
builds_per_day: 2
```

Will build the project twice per day.

### file_github_issue (optional) {#file_github_issue}
Whether to mirror issues on github instead of having them only in the OSS-Fuzz
tracker.

### disable_remediation (optional) {#disable_remediation}
Opt out of receiving remediation for all new and existing bugs. If remediation
is disabled, all disclosure notifications will not include any proposed code
changes. If enabled (default), proposed code changes and comments to remediate
bugs may be automatically included in disclosure that is private during the
embargo of each issue on a case-by-case basis basis.

### disable_remediation_pre_review (optional) {#disable_remediation_pre_review}
Opt out of human-in-the-loop pre-review for proposed remediation code changes.
If this is enabled, proposed code changes will be included in disclosure
notifications without prior manual review by the OSS-Fuzz team. If disabled
(default), all proposed remediation changes will be reviewed by a human before
being shared.

## Dockerfile {#dockerfile}

This configuration file defines the Docker image for your project. Your [build.sh](#buildsh) script will be executed in inside the container you define.
For most projects, the image is simple:
```docker
FROM gcr.io/oss-fuzz-base/base-builder       # base image with clang toolchain
RUN apt-get update && apt-get install -y ... # install required packages to build your project
RUN git clone <git_url> <checkout_dir>       # checkout all sources needed to build your project
WORKDIR <checkout_dir>                       # current directory for the build script
COPY build.sh fuzzer.cc $SRC/                # copy build script and other fuzzer files in src dir
```
In the above example, the git clone will check out the source to `$SRC/<checkout_dir>`.

Depending on your project's language, you will use a different base image,
for instance `FROM gcr.io/oss-fuzz-base/base-builder-go` for golang.

For an example, see
[expat/Dockerfile](https://github.com/google/oss-fuzz/tree/master/projects/expat/Dockerfile)
or
[syzkaller/Dockerfile](https://github.com/google/oss-fuzz/blob/master/projects/syzkaller/Dockerfile).

In the case of a project with multiple languages/toolchains needed,
you can run installation scripts `install_lang.sh` where lang is the language needed.
You also need to setup environment variables needed by this toolchain, for example `GOPATH` is needed by golang.
For an example, see
[ecc-diff-fuzzer/Dockerfile](https://github.com/google/oss-fuzz/blob/master/projects/ecc-diff-fuzzer/Dockerfile).
where we use `base-builder-rust`and install golang

Runtime dependencies of your project, such as third-party static libraries, will
not be instrumented if you build them in the Dockerfile. In most cases, you will
want to build them in `build.sh` instead.

## build.sh {#buildsh}

This file defines how to build binaries for [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) in your project.
The script is executed within the image built from your [Dockerfile](#Dockerfile).

In general, this script should do the following:

- Build the project using your build system with the correct compiler.
- Provide compiler flags as [environment variables](#Requirements).
- Build your [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) and link your project's build with libFuzzer.

Resulting binaries should be placed in `$OUT`.

Here's an example from Expat ([source](https://github.com/google/oss-fuzz/blob/master/projects/expat/build.sh)):

```bash
#!/bin/bash -eu

./buildconf.sh
# configure scripts usually use correct environment variables.
./configure

make clean
make -j$(nproc) all

$CXX $CXXFLAGS -std=c++11 -Ilib/ \
    $SRC/parse_fuzzer.cc -o $OUT/parse_fuzzer \
    $LIB_FUZZING_ENGINE .libs/libexpat.a

cp $SRC/*.dict $SRC/*.options $OUT/
```

If your project is written in Go, check out the [Integrating a Go project]({{ site.baseurl }}//getting-started/new-project-guide/go-lang/) page.

**Note:**

1. Don't assume the fuzzing engine is libFuzzer by default, because we generate builds for libFuzzer, AFL++, Honggfuzz, and Centipede fuzzing engine configurations. Instead, link the fuzzing engine using $LIB_FUZZING_ENGINE.
2. Make sure that the binary names for your [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) contain only
alphanumeric characters, underscore(_) or dash(-). Otherwise, they won't run on our infrastructure.
3. Don't remove source code files. They are needed for code coverage.

### Temporarily disabling code instrumentation during builds

In some cases, it's not necessary to instrument every 3rd party library or tool that supports the build target. Use the following snippet to build tools or libraries without instrumentation:


```
CFLAGS_SAVE="$CFLAGS"
CXXFLAGS_SAVE="$CXXFLAGS"
unset CFLAGS
unset CXXFLAGS
export AFL_NOOPT=1

#
# build commands here that should not result in instrumented code.
#

export CFLAGS="${CFLAGS_SAVE}"
export CXXFLAGS="${CXXFLAGS_SAVE}"
unset AFL_NOOPT
```

### build.sh script environment

When your build.sh script is executed, the following locations are available within the image:

| Location| Env Variable | Description |
|---------| ------------ | ----------  |
| `/out/` | `$OUT`         | Directory to store build artifacts (fuzz targets, dictionaries, options files, seed corpus archives). |
| `/src/` | `$SRC`         | Directory to checkout source files. |
| `/work/`| `$WORK`        | Directory to store intermediate files. |

Although the files layout is fixed within a container, environment variables are
provided so you can write retargetable scripts.

In case your fuzz target uses the [FuzzedDataProvider] class, make sure it is
included via `#include <fuzzer/FuzzedDataProvider.h>` directive.

[FuzzedDataProvider]: https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider

### build.sh requirements {#Requirements}

Only binaries without an extension are accepted as targets. Extensions are reserved for other artifacts, like .dict.

You *must* use the special compiler flags needed to build your project and fuzz targets.
These flags are provided in the following environment variables:

| Env Variable           | Description
| -------------          | --------
| `$CC`, `$CXX`, `$CCC`  | The C and C++ compiler binaries.
| `$CFLAGS`, `$CXXFLAGS` | C and C++ compiler flags.
| `$LIB_FUZZING_ENGINE`  | C++ compiler argument to link fuzz target against the prebuilt engine library (e.g. libFuzzer).

You *must* use `$CXX` as a linker, even if your project is written in pure C.

Most well-crafted build scripts will automatically use these variables. If not,
pass them manually to the build tool.

See the [Provided Environment Variables](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/README.md#provided-environment-variables) section in
`base-builder` image documentation for more details.

### Static and dynamic linking of libraries
The `build.sh` should produce fuzzers that are statically linked. This is because the
fuzzer build environment is different to the fuzzer runtime environment and if your
project depends on third party libraries then it is likely they will not be present
in the execution environment. Thus, any shared libraries you may install or compile in
`build.sh` or `Dockerfile` will not be present in the fuzzer runtime environment. There
are exceptions to this rule, and for further information on this please see the [fuzzer environment]({{ site.baseurl }}/further-reading/fuzzer-environment/) page.

## Disk space restrictions

Our builders have a disk size of 250GB (this includes space taken up by the OS). Builds must keep peak disk usage below this.

In addition, please keep the size of the build (everything copied to `$OUT`) small (<10GB uncompressed). The build is repeatedly transferred and unzipped during fuzzing and runs on VMs with limited disk space.

## Fuzzer execution environment

For more on the environment that
your [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) run in, and the assumptions you can make, see the [fuzzer environment]({{ site.baseurl }}/further-reading/fuzzer-environment/) page.

## Testing locally

You can build your docker image and fuzz targets locally, so you can test them before you push them to the OSS-Fuzz repository.

1. Run the same helper script you used to create your directory structure, this time using it to build your docker image and [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target):

    ```bash
    $ cd /path/to/oss-fuzz
    $ python3 infra/helper.py build_image $PROJECT_NAME
    $ python3 infra/helper.py build_fuzzers --sanitizer <address/memory/undefined> $PROJECT_NAME
    ```

    The built binaries appear in the `/path/to/oss-fuzz/build/out/$PROJECT_NAME`
    directory on your machine (and `$OUT` in the container).

    **Note:** You *must* run your fuzz target binaries inside the base-runner docker
    container to make sure that they work properly.

2. Find failures to fix by running the `check_build` command:

    ```bash
    $ python3 infra/helper.py check_build $PROJECT_NAME
    ```

3. If you want to test changes against a particular fuzz target, run the following command:

    ```bash
    $ python3 infra/helper.py run_fuzzer --corpus-dir=<path-to-temp-corpus-dir> $PROJECT_NAME <fuzz_target>
    ```

4. We recommend taking a look at your code coverage as a test to ensure that
your fuzz targets get to the code you expect. This would use the corpus
generated from the previous `run_fuzzer` step in your local corpus directory.

    ```bash
    $ python3 infra/helper.py build_fuzzers --sanitizer coverage $PROJECT_NAME
    $ python3 infra/helper.py coverage $PROJECT_NAME --fuzz-target=<fuzz_target> --corpus-dir=<path-to-temp-corpus-dir>
    ```

You may need to run `python3 infra/helper.py pull_images` to use the latest
coverage tools. Please refer to
[code coverage]({{ site.baseurl }}/advanced-topics/code-coverage/) for detailed
information on code coverage generation.


**Note:** Currently, we only support AddressSanitizer (address) and UndefinedBehaviorSanitizer (undefined)
configurations by default.
MemorySanitizer is recommended, but needs to be enabled manually since you must build all runtime dependencies with MemorySanitizer.
<b>Make sure to test each
of the supported build configurations with the above commands (build_fuzzers -> run_fuzzer -> coverage).</b>

If everything works locally, it should also work on our automated builders and ClusterFuzz. If you check in
your files and experience failures, review your [dependencies]({{ site.baseurl }}/further-reading/fuzzer-environment/#dependencies).

## Debugging Problems

If you run into problems, our [Debugging page]({{ site.baseurl }}/advanced-topics/debugging/) lists ways to debug your build scripts and
[fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target).

## Efficient fuzzing

To improve your fuzz target ability to find bugs faster, you should consider the
following ways:

### Seed Corpus

Most fuzzing engines use evolutionary fuzzing algorithms. Supplying a seed
corpus consisting of good sample inputs is one of the best ways to improve [fuzz
target]({{ site.baseurl }}/reference/glossary/#fuzz-target)'s coverage.

To provide a corpus for `my_fuzzer`, put `my_fuzzer_seed_corpus.zip` file next
to the [fuzz target]({{ site.baseurl }}/reference/glossary/#fuzz-target)'s binary in `$OUT` during the build. Individual files in this
archive will be used as starting inputs for mutations. You can store the corpus
next to source files, generate during build or fetch it using curl or any other
tool of your choice.
(example: [boringssl](https://github.com/google/oss-fuzz/blob/master/projects/boringssl/build.sh#L41)).

Seed corpus files will be used for cross-mutations and portions of them might appear
in bug reports or be used for further security research. It is important that corpus
has an appropriate and consistent license.

OSS-Fuzz only: See also [Accessing Corpora]({{ site.baseurl }}/advanced-topics/corpora/) for information about getting access to the corpus we are currently using for your fuzz targets.

### Dictionaries

Dictionaries hugely improve fuzzing efficiency for inputs with lots of similar
sequences of bytes. [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html#dictionaries)

Put your dict file in `$OUT`. If the dict filename is the same as your target
binary name (i.e. `%fuzz_target%.dict`), it will be automatically used. If the
name is different (e.g. because it is shared by several targets), specify this
in .options file:

```
[libfuzzer]
dict = dictionary_name.dict
```

It is common for several [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target)
to reuse the same dictionary if they are fuzzing very similar inputs.
(example: [expat](https://github.com/google/oss-fuzz/blob/ad88a2e5295d91251d15f8a612758cd9e5ad92db/projects/expat/parse_fuzzer.options)).

### Input Size

By default, the fuzzing engine will generate input of any arbitrary length.
This might be useful to try corner cases that could lead to a
security vulnerability. However, if large inputs are not necessary to
increase the coverage of your target API, it is important to add a limit
here to significantly improve performance.

```cpp
if (size < kMinInputLength || size > kMaxInputLength)
  return 0;
```

## Checking in to the OSS-Fuzz repository

Once you've tested your fuzzing files locally, fork OSS-Fuzz, commit, and push to the fork. Then
create a pull request with your change. Follow the
[Forking Project](https://guides.github.com/activities/forking/) guide if you're new to contributing
via GitHub.

### Copyright headers

Please include copyright headers for all files checked in to oss-fuzz:

```
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
```

**Exception:** If you're porting a fuzz target from Chromium, keep the original Chromium license header.

## Reviewing results

Once your change is merged, your project and fuzz targets should be automatically built and run on
ClusterFuzz after a short while (&lt; 1 day). If you think there's a problem, you can check your project's [build status](https://oss-fuzz-build-logs.storage.googleapis.com/index.html).

Use the [ClusterFuzz web interface](https://oss-fuzz.com/) to review the following:
* Crashes generated
* Code coverage statistics
* Fuzzer statistics
* Fuzzer performance analyzer (linked from fuzzer statistics)

**Note:** Your Google Account must be listed in [project.yaml](#projectyaml) for you to have access to the ClusterFuzz web interface.

### Status Badge

![Example
Badge](https://oss-fuzz-build-logs.storage.googleapis.com/badges/curl.svg)

Once your project has started [building](https://oss-fuzz-build-logs.storage.googleapis.com/index.html), we'd love it if you added our badge in
your project's README. This allows you to see bugs found by your OSS-Fuzz
integration at a glance. See
[brotli](https://github.com/google/brotli#introduction)'s
README for an example.

Adding it is super easy, just follow this template:
```markdown
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:<project>)
```

## Monitoring performance via Fuzz Introspector

As soon as your project is run with ClusterFuzz (< 1 day), you can view the Fuzz
Introspector report for your project.
[Fuzz Introspector](https://github.com/ossf/fuzz-introspector) helps you
understand your fuzzers' performance and identify any potential blockers.
It provides individual and aggregated fuzzer reachability and coverage reports.
You can monitor each fuzzer's static reachability potential and compare it
against dynamic coverage and identify any potential bottlenecks.
Fuzz Introspector can offer suggestions on increasing coverage by adding new
fuzz targets or modify existing ones.
Fuzz Introspector reports can be viewed from the [OSS-Fuzz
homepage](https://oss-fuzz.com/) or through this
[index](http://oss-fuzz-introspector.storage.googleapis.com/index.html).
Fuzz Introspector support C and C++ projects.
Support for Java and Python projects is in the progress.

You can view the [Fuzz Introspector report for bzip2](https://storage.googleapis.com/oss-fuzz-introspector/bzip2/inspector-report/20221017/fuzz_report.html)
as an example.

---

### Oss Fuzz Architecture (`docs/oss-fuzz/architecture.md`)

---
layout: default
title: Architecture
permalink: /architecture/
nav_order: 1
parent: OSS-Fuzz
---

# Architecture


The process works like this:

1. A maintainer of an open source project (or an outside volunteer) creates
one or more [fuzz targets](https://llvm.org/docs/LibFuzzer.html#fuzz-target)
and [integrates]({{ site.baseurl }}/advanced-topics/ideal-integration/) them
with the project's build and test system.
1. The project is [accepted to OSS-Fuzz]({{ site.baseurl }}/getting-started/accepting-new-projects/) and the developer commits their build configurations.
1. The OSS-Fuzz [builder](https://github.com/google/oss-fuzz/tree/master/infra/build) builds the project from the committed configs.
1. The builder uploads the fuzz targets to the OSS-Fuzz GCS bucket.
1. [ClusterFuzz]({{ site.baseurl }}/further-reading/clusterfuzz) downloads the fuzz targets and begins to fuzz the projects.
1. When Clusterfuzz finds a
  bug, it reports the issue automatically to the OSS-Fuzz
  [issue tracker](https://bugs.chromium.org/p/oss-fuzz/issues/list) 
  ([example](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9)).
  ([Why use a different tracker?]({{ site.baseurl }}/faq/#why-do-you-use-a-different-issue-tracker-for-reporting-bugs-in-oss-projects))
1. Project owners are CCed on the bug report.
1. The project developer fixes the bug upstream and credits OSS-Fuzz for the
  discovery (the commit message should contain the string **'Credit to OSS-Fuzz'**).

Once the developer fixes the bug, [ClusterFuzz]({{ site.baseurl }}/further-reading/clusterfuzz) automatically
verifies the fix, adds a comment, and closes the issue ([example](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53#c3)). After the fix is verified or 90 days after reporting (whichever is earlier), the issue becomes [public]({{ site.baseurl }}/getting-started/bug-disclosure-guidelines/).

---

### Reference Glossary (`docs/reference/glossary.md`)

---
layout: default
title: Glossary
nav_order: 1
permalink: /reference/glossary/
parent: Reference
---

# Glossary

For general fuzzing terms, see the [glossary] from [google/fuzzing] project.

[glossary]: https://github.com/google/fuzzing/blob/master/docs/glossary.md
[google/fuzzing]: https://github.com/google/fuzzing

- TOC
{:toc}
---

## OSS-Fuzz specific terms

### ClusterFuzz

A scalable fuzzing infrastructure that is used for OSS-Fuzz backend.
[ClusterFuzz] is also used to fuzz Chrome and many other projects. A quick
overview of ClusterFuzz user interface is available on this [page].

[page]: {{ site.baseurl }}/further-reading/clusterfuzz
[ClusterFuzz]: https://github.com/google/clusterfuzz

### Fuzz Target

In addition to its
[general definition](https://github.com/google/fuzzing/blob/master/docs/glossary.md#fuzz-target),
in OSS-Fuzz a fuzz target can be used to
[reproduce bug reports]({{ site.baseurl }}/advanced-topics/reproducing/).
It is recommended to use it for regression testing as well (see
[ideal integration]({{ site.baseurl }}/advanced-topics/ideal-integration/)).

### Job type

Or **Fuzzer Build**.

This refers to a build that contains all the [fuzz targets] for a given
[project](#project), is run with a specific [fuzzing engine], in a specific
build mode (e.g. with enabled/disabled assertions), and optionally combined
with a [sanitizer].

For example, we have a "libfuzzer_asan_sqlite" job type, indicating a build of
all sqlite3 [fuzz targets] using [libFuzzer](http://libfuzzer.info) and
[ASan](http://clang.llvm.org/docs/AddressSanitizer.html).

### Project

A project is an open source software project that is integrated with OSS-Fuzz.
Each project has a single set of configuration files 
(example: [expat](https://github.com/google/oss-fuzz/tree/master/projects/expat))
and may have one or more [fuzz targets]
(example: [openssl](https://github.com/openssl/openssl/blob/master/fuzz/)).

### Reproducer

Or a **testcase**.

A [test input] that causes a specific bug to reproduce.

[fuzz targets]: https://github.com/google/fuzzing/blob/master/docs/glossary.md#fuzz-target
[fuzzing engine]: https://github.com/google/fuzzing/blob/master/docs/glossary.md#fuzzing-engine
[sanitizer]: https://github.com/google/fuzzing/blob/master/docs/glossary.md#sanitizer
[test input]: https://github.com/google/fuzzing/blob/master/docs/glossary.md#test-input

### Sanitizers

Fuzzers are usually built with one or more [sanitizer](https://github.com/google/sanitizers) enabled. 

```bash
$ python3 infra/helper.py build_fuzzers --sanitizer undefined json
```

Supported sanitizers:

| Sanitizer | Description
| ------------ | ----------
| `address` *(default)* | [Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) with [Leak Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer).
| `undefined` | [Undefined Behavior Sanitizer](http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html).
| `memory` | [Memory Sanitizer](https://github.com/google/sanitizers/wiki/MemorySanitizer).<br/>*NOTE: It is critical that you build __all__ the code in your program (including libraries it uses) with Memory Sanitizer. Otherwise, you will see false positive crashes due to an inability to see initializations in uninstrumented code.*
| `coverage` | Used for generating code coverage reports. See [Code Coverage doc]({{ site.baseurl }}/advanced-topics/code-coverage/).

Compiler flag values for predefined configurations are specified in the [Dockerfile](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/Dockerfile). 
These flags can be overridden by specifying `$SANITIZER_FLAGS` directly.

You can choose which configurations to automatically run your fuzzers with in `project.yaml` file (e.g. [sqlite3](https://github.com/google/oss-fuzz/tree/master/projects/sqlite3/project.yaml)).

### Architectures
ClusterFuzz supports fuzzing on x86_64 (aka x64) by default. However you can also fuzz using AddressSanitizer and libFuzzer on i386 (aka x86, or 32 bit) by specifying the `$ARCHITECTURE` build environment variable using the `--architecture` option:

```bash
python3 infra/helper.py build_fuzzers --architecture i386 json
```

---

### Reference Reference (`docs/reference/reference.md`)

---
layout: default
title: Reference
has_children: true
nav_order: 7
permalink: /reference/
---

# Reference

---

### Reference Useful Links (`docs/reference/useful_links.md`)

---
layout: default
title: Useful links
nav_order: 2
permalink: /reference/useful-links/
parent: Reference
---

# Useful links

- TOC
{:toc}
---

## Web Interface

* The main page: [oss-fuzz.com](https://oss-fuzz.com)

## Build Status

* [This page](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
  gives the latest build logs for each project.

## Blog posts

* 2016-12-01 - Announcing OSS-Fuzz: Continuous fuzzing for open source software
([Open Source](https://opensource.googleblog.com/2016/12/announcing-oss-fuzz-continuous-fuzzing.html),
[Testing](https://testing.googleblog.com/2016/12/announcing-oss-fuzz-continuous-fuzzing.html),
[Security](https://security.googleblog.com/2016/12/announcing-oss-fuzz-continuous-fuzzing.html))
* 2017-05-08 - OSS-Fuzz: Five months later, and rewarding projects
([Open Source](https://opensource.googleblog.com/2017/05/oss-fuzz-five-months-later-and.html),
[Testing](https://testing.googleblog.com/2017/05/oss-fuzz-five-months-later-and.html),
[Security](https://security.googleblog.com/2017/05/oss-fuzz-five-months-later-and.html))
* 2018-11-06 - A New Chapter for OSS-Fuzz
([Security](https://security.googleblog.com/2018/11/a-new-chapter-for-oss-fuzz.html))
* 2020-10-09 - [Fuzzing internships for Open Source Software](https://security.googleblog.com/2020/10/fuzzing-internships-for-open-source.html)
* 2020-12-07 - [Improving open source security during the Google summer internship program](https://security.googleblog.com/2020/12/improving-open-source-security-during.html)
* 2021-03-10 - [Fuzzing Java in OSS-Fuzz](https://security.googleblog.com/2021/03/fuzzing-java-in-oss-fuzz.html)
* 2021-12-16 - [Improving OSS-Fuzz and Jazzer to catch Log4Shell](https://security.googleblog.com/2021/12/improving-oss-fuzz-and-jazzer-to-catch.html)
* 2022-09-08 - [Fuzzing beyond memory corruption: Finding broader classes of vulnerabilities automatically](https://security.googleblog.com/2022/09/fuzzing-beyond-memory-corruption.html)
* 2023-02-01 - [Taking the next step: OSS-Fuzz in 2023](https://security.googleblog.com/2023/02/taking-next-step-oss-fuzz-in-2023.html)

## Tutorials

* [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html)
* [libFuzzer tutorial](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md)
* [libFuzzer workshop](https://github.com/Dor1s/libfuzzer-workshop)
* [Structure-Aware Fuzzing with libFuzzer](https://github.com/google/fuzzer-test-suite/blob/master/tutorial/structure-aware-fuzzing.md)
* [Chromium Fuzzing Page](https://chromium.googlesource.com/chromium/src/testing/libfuzzer/)
* [Chromium Efficient Fuzzing Guide](https://chromium.googlesource.com/chromium/src/testing/libfuzzer/+/HEAD/efficient_fuzzing.md)
* [ClusterFuzz documentation](https://google.github.io/clusterfuzz/)

---

### Research Target Generation (`docs/research/target_generation.md`)

---
layout: default
nav_exclude: true
permalink: /research/llms/target_generation/
---
# Fuzz target generation using LLMs

[Read our announcement blog.](https://security.googleblog.com/2023/08/ai-powered-fuzzing-breaking-bug-hunting.html)

# Background

[OSS-Fuzz](http://github.com/google/oss-fuzz) performs continuous fuzzing of [1000+](https://github.com/google/oss-fuzz/tree/master/projects) open source projects across most major languages. To integrate a new project, a human typically analyzes the attack surface of a library and writes [fuzz targets](https://github.com/google/fuzzing/blob/master/docs/glossary.md#fuzz-target) (also called fuzzing harnesses) to exercise the relevant code. Linked with a [fuzzing engine](https://github.com/google/fuzzing/blob/master/docs/glossary.md#fuzzing-engine) (e.g. libFuzzer, AFL, Centipede), this enables coverage-guided fuzzing for all OSS-Fuzz projects. Depending on the complexity of the project, writing fuzz targets typically requires several hours of manual work and sufficient background knowledge of the project.

Additionally, the main challenge for most integrated OSS-Fuzz projects is ensuring high code coverage. Most OSS-Fuzz projects have fairly low runtime coverage ([~30%](http://introspector.oss-fuzz.com/)) despite millions of hours of CPU time. This means we are not finding vulnerabilities in approximately 70% of each project that we’re fuzzing. Our [preliminary research](https://dl.acm.org/doi/abs/10.1145/3605157.3605177) found that many[ fuzz blockers](https://github.com/ossf/fuzz-introspector/blob/main/doc/Glossary.md#fuzz-blockers) (as determined by [FuzzIntrospector](https://introspector.oss-fuzz.com/)) are because of deficiencies in existing targets, rather than deficiencies in fuzzing engines.

Generating fuzz targets via LLMs can reduce the manual effort required to more thoroughly fuzz existing projects in OSS-Fuzz as well as integrating new projects into OSS-Fuzz.


# Goals

Our ideal end state of this research is to use LLMs for two use cases:

1. Completely automatic fuzz target generation (or modification of existing targets) for existing OSS-Fuzz projects to unblock fuzz blockers and increase project code coverage (and bugs found) for free. 
2. Completely automatic fuzz target generation for completely new OSS-Fuzz projects. This is much more challenging than 1, and is an extension of it. 

Our current experiments focus on the first use case for C/C++ projects. This report serves as a preliminary investigation into how effective LLMs are for this use case. More detailed results and the experimentation framework for our research will be published at a later date. 


# Experiment framework

To discover whether an LLM could successfully write new fuzz targets, we built an evaluation framework that connects OSS-Fuzz to Google’s LLMs, conducts the experiment, and evaluates the results. The steps look like this:



1. OSS-Fuzz’s [Fuzz Introspector tool](http://introspector.oss-fuzz.com/) identifies an under-fuzzed, high-potential, portion of the target project’s code and passes the code to the evaluation framework. 
2. The evaluation framework creates a prompt that the LLM will use to write the new fuzz target. The prompt includes project specific information.
3. The evaluation framework takes the fuzz target generated by the LLM and runs the new target. 
4. The evaluation framework observes the run for any change in code coverage or crashes.
5. In the event that the fuzz target fails to compile, the evaluation framework prompts the LLM to write a revised fuzz target that addresses the compilation errors.


## 1. Identifying high potential portions of the project’s code

We leverage [Fuzz Introspector](https://introspector.oss-fuzz.com/) ([example JSON endpoint](https://introspector.oss-fuzz.com/api/far-reach-but-low-coverage?project=tinyxml2)) to provide us with a list of functions with low runtime coverage (but high potential to reach more code coverage). These are turned into benchmark YAML files, which consist of an OSS-Fuzz project, and a list of function signatures to generate new targets for. 

We have started with a small set of benchmarks, and will gradually scale this to larger, automated sets of benchmarks taken from all of OSS-Fuzz as we improve the function selection and prompt generation process.

Example benchmark (YAML):

```yaml
functions:
- XML_Parser XMLCALL XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char
  *context, const XML_Char *encodingName)
- XML_Parser XMLCALL XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
- XML_Bool XMLCALL XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
- static enum XML_Error PTRCALL externalParEntInitProcessor(XML_Parser parser, const
  char *s, const char *end, const char **nextPtr)
project: expat
target_path: /src/expat/expat/fuzz/xml_parse_fuzzer.c
target_name: xml_parse_fuzzer_UTF-8
```

## 2. Prompt generation

We dynamically generate a prompt based on a template ([example](https://storage.googleapis.com/oss-fuzz-llm-targets-public/jsoncpp-json-value-removeindex/prompts.txt)).

As part of our experimentation, we tried various different prompt approaches. So far, the best results have come from including:

*   One example of an existing function signature and fuzz target from the project under test, formatted into problem and solution structure. Too many examples yields worse results.
*   Two examples from other projects in OSS-Fuzz, formatted in the same way.
*   Examples of how to leverage [FuzzedDataProvider](https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider) to generate inputs for function arguments.
*   A priming that gives the task context.
*   Examples of code anti-patterns to avoid.

The dynamically generated sections today include examples of existing fuzz targets from both other projects on OSS-Fuzz as well as one example from the project under test. We have other unexplored ideas including more structured information about the function under test, such as:

*   Relevant data structure definitions
*   Function implementations of the function under test and related functions
*   Usages of the function under test and related functions


## 3. Build and run

We leverage the OSS-Fuzz build infrastructure to build new targets by replacing an existing target’s source code with the newly generated target source code.  

OSS-Fuzz projects often have strict compiler flags on by default. To make compilation easier, we also implemented a [compiler wrapper](https://github.com/google/oss-fuzz/blob/d78275b4e2e17d3d8f12b99db2b51de4b114edb3/infra/base-images/base-builder/jcc.go) that:

*   Turns off compiler warnings to prevent trivial issues such as missing pointer casts from blocking compilation. 
*   Re-compiles targets as C++ (to leverage [FuzzedDataProvider](https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider)).


## 4. Measuring quality of generated targets

An important part of our research is to define metrics to measure the quality of generated targets. 

These metrics are:

*   Syntax correctness and project consistency. This is measured by its compilation result. For example: whether it compiles successfully, does it call functions in the project correctly without hallucination.
*   Whether it crashes instantly or within the fuzz target. This often means that there is some miscalled API and the crashes are likely to be false positives. 
*   **New code coverage**. This is measured by the new lines it covered compared to all existing targets in OSS-Fuzz for the same project. 

All of these metrics can be automatically computed for a given generated target. 


## 5. LLM Code Fixer

The fuzz targets generated by LLM often contain various trivial defects,  which can be fixed by a separate LLM query.

The prompt of the code fixing query is structured as follows, where the raw code and error are respectively replaced with the fuzz target source code generated by the LLM and the build error messages extracted from pages of build logs:

````
Given the following code and its build error message, fix the code without affecting its functionality.
First explain the reason, then output the whole fixed code.
If a function is missing, fix it by including the related libraries.
Code:
```
{raw_code}
```
Build error message:
```
{error}
```
Fixed code:
````

Several rounds of code fixing queries are required for some cases. For example, when multiple defects incurs several error messages, sometimes LLM tends to only fix one of them at a time. Similarly, new defects may be introduced during code fixing. In these cases, we found iteratively querying LLM with the same prompt structure will gradually fix all errors.

LLM often proposes several responses for each query, we prefer the one with the longest code. This is an implementation decision to avoid a quadratically increasing number of targets to build (e.g. the LLMs could propose 4 new targets across N iterations) and to avoid the LLM deleting the function code to fix build failures.

Additionally, we also check that the generated target includes a call to the requested function to test. If it does not, this is surfaced as an error to the LLM. 	


### Example

[Prompt](https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmldocument-print/fixes/04-F4/prompt.txt): Incorrect target with missing arguments passed to target function.

[After fix](https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmldocument-print/fixes/04-F4/01.cpp): Correct function argument added.

# Results

Initially, getting any compilable output was a challenge. We were able to improve this via prompt engineering and our compiler wrapper to having [14/31 tested OSS-Fuzz projects](https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=benchmarks/) successfully compile new targets and increase coverage. The successful examples and prompts are published [here](https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html). 

We see a wide range of coverage improvements from 0-31% code coverage increases.

The top coverage increases, aggregated across all benchmarks per OSS-Fuzz project are:


<table>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">31%
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">6%
   </td>
  </tr>
  <tr>
   <td style="background-color: null">expat 
   </td>
   <td style="background-color: null">4%
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libplist
   </td>
   <td style="background-color: null">4%
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libxml2
   </td>
   <td style="background-color: null">1%
   </td>
  </tr>
  <tr>
   <td style="background-color: null">elfutils
   </td>
   <td style="background-color: null">1%
   </td>
  </tr>
</table>


The best result we’ve had is with the TinyXML2 project, where we managed to increase fuzz coverage from [38%](https://storage.googleapis.com/oss-fuzz-coverage/tinyxml2/reports/20230801/linux/report.html) line coverage to [69%](https://storage.googleapis.com/oss-fuzz-coverage/llm-results/tinyxml2/linux/report.html) line coverage without any interventions.







Additionally, we targeted OpenSSL from the perspective of discovering past vulnerabilities that were not found due to lack of fuzzing coverage. We were able to replicate [a similar fuzz target](https://storage.googleapis.com/oss-fuzz-llm-targets-public/openssl-ossl_punycode_decode/targets/15.c) that rediscovered [CVE-2022-3602](https://nvd.nist.gov/vuln/detail/CVE-2022-3602).




# Future work

We’ve seen very promising early results in this space and will continue our research.


## 1. Continue research

There are a number of areas we’d like to further research on:



*   Expand benchmarks to all of OSS-Fuzz. We’d like to expand the set of benchmarks to cover all of OSS-Fuzz.
*   Continued prompt engineering and experimentation with project-specific context, such as more structured context (e.g. structure definitions, implementations) around the relevant function to test. 
*   Model fine-tuning
*   Expand to other languages beyond C/C++
*   Expand research to completely new projects with no existing OSS-Fuzz integration.  


## 2. Open source evaluation framework

We plan to open source the evaluation framework we’ve built to help test arbitrary auto-fuzz target generation capabilities. We hope that OSS-Fuzz can serve as a valuable benchmarking platform for researchers in this space. 


## 3. OSS-Fuzz integration

Ultimately, the goal is to integrate the results of this research into OSS-Fuzz, to provide:



*   Free coverage increases for existing projects
*   Automated onboarding of new projects, and tools to help maintainers write manual fuzz targets. 


# Appendix


## Successful benchmark results

<table>
  <tr>
   <td style="background-color: null"><strong>Project</strong>
   </td>
   <td style="background-color: null"><strong>Function</strong>
   </td>
   <td style="background-color: null"><strong>Output</strong>
   </td>
   <td style="background-color: null"><strong>Build rate</strong>
   </td>
   <td style="background-color: null"><strong>Max Coverage</strong>
   </td>
   <td style="background-color: null"><strong>Max Line coverage diff</strong>
   </td>
   <td style="background-color: null"><strong>Reports</strong>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmldocument-print
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmldocument-print/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-print/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-print/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
29.74</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
11.16</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-print/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmldocument-deepcopy
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmldocument-deepcopy/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-deepcopy/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-deepcopy/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.8</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
4.45</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-deepcopy/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-setattribute
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-setattribute/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-setattribute/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-setattribute/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
75</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.08</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
3.77</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-setattribute/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libplist
   </td>
   <td style="background-color: null">plist_print
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libplist-plist_print/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_print/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_print/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
12.88</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
3.42</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_print/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-doubletext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-doubletext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-doubletext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-doubletext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.61</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
3.28</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-doubletext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-booltext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-booltext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-booltext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-booltext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.18</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.9</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-booltext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-insertnewunknown
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-insertnewunknown/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewunknown/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewunknown/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.67</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.64</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewunknown/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-int64text
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-int64text/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-int64text/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-int64text/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.91</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.64</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-int64text/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_compare
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_compare/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_compare/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_compare/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
75</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
29.68</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.47</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_compare/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-floattext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-floattext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-floattext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-floattext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.09</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.45</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-floattext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-inttext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-inttext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-inttext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-inttext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
75</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.2</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.41</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-inttext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-unsigned64text
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-unsigned64text/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsigned64text/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsigned64text/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.74</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.22</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsigned64text/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyobjloader
   </td>
   <td style="background-color: null">tinyobj-objreader-parsefromfile
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyobjloader-tinyobj-objreader-parsefromfile/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-objreader-parsefromfile/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-objreader-parsefromfile/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
5.7</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.16</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-objreader-parsefromfile/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-unsignedtext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-unsignedtext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsignedtext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsignedtext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.53</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.15</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-unsignedtext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-shallowclone
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-shallowclone/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowclone/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowclone/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.03</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.07</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowclone/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_replaceiteminobject
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_replaceiteminobject/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobject/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobject/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
27.56</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.98</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobject/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-gettext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-gettext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-gettext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-gettext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.42</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.96</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-gettext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-shallowequal
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-shallowequal/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowequal/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowequal/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.58</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.96</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-shallowequal/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_duplicate
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_duplicate/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_duplicate/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_duplicate/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
27.4</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.89</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_duplicate/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">expat
   </td>
   <td style="background-color: null">xml_externalentityparsercreate
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/expat-xml_externalentityparsercreate/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_externalentityparsercreate/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_externalentityparsercreate/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
12.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.88</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_externalentityparsercreate/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_replaceiteminobjectcasesensitive
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_replaceiteminobjectcasesensitive/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobjectcasesensitive/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobjectcasesensitive/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.54</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.85</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_replaceiteminobjectcasesensitive/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-insertnewcomment
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-insertnewcomment/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewcomment/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewcomment/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.61</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.85</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewcomment/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">expat
   </td>
   <td style="background-color: null">xml_parsercreatens
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/expat-xml_parsercreatens/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_parsercreatens/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_parsercreatens/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
12.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
45.6</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.84</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=expat-xml_parsercreatens/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-deleteattribute
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-deleteattribute/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-deleteattribute/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-deleteattribute/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.73</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.7</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-deleteattribute/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-insertnewdeclaration
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-insertnewdeclaration/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewdeclaration/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewdeclaration/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.7</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewdeclaration/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-insertnewchildelement
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-insertnewchildelement/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewchildelement/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewchildelement/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
24.88</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.51</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewchildelement/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlnode-previoussiblingelement
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlnode-previoussiblingelement/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlnode-previoussiblingelement/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlnode-previoussiblingelement/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.08</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.43</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlnode-previoussiblingelement/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyobjloader
   </td>
   <td style="background-color: null">tinyobj-loadobj
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyobjloader-tinyobj-loadobj/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-loadobj/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-loadobj/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
4.33</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.35</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-loadobj/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyobjloader
   </td>
   <td style="background-color: null">tinyobj-material_t-material_t
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyobjloader-tinyobj-material_t-material_t/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-material_t-material_t/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-material_t-material_t/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
23.91</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.35</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyobjloader-tinyobj-material_t-material_t/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmlelement-insertnewtext
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmlelement-insertnewtext/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewtext/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewtext/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
24.42</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.32</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmlelement-insertnewtext/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">elfutils
   </td>
   <td style="background-color: null">dwfl_module_relocate_address
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/elfutils-dwfl_module_relocate_address/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwfl_module_relocate_address/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwfl_module_relocate_address/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
7.81</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.1</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwfl_module_relocate_address/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libxml2
   </td>
   <td style="background-color: null">xmlschemavalidatefile
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libxml2-xmlschemavalidatefile/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmlschemavalidatefile/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmlschemavalidatefile/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
4.18</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.93</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmlschemavalidatefile/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">tinyxml2
   </td>
   <td style="background-color: null">tinyxml2-xmldocument-loadfile
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/tinyxml2-tinyxml2-xmldocument-loadfile/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-loadfile/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-loadfile/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.17</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.9</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=tinyxml2-tinyxml2-xmldocument-loadfile/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">speex
   </td>
   <td style="background-color: null">ogg_stream_packetin
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/speex-ogg_stream_packetin/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_packetin/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_packetin/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
8.06</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.55</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_packetin/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libxml2
   </td>
   <td style="background-color: null">xmltextreadersetschema
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libxml2-xmltextreadersetschema/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreadersetschema/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreadersetschema/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.44</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.48</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreadersetschema/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libxml2
   </td>
   <td style="background-color: null">xmltextreaderschemavalidate
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libxml2-xmltextreaderschemavalidate/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidate/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidate/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
4.03</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.36</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidate/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libplist
   </td>
   <td style="background-color: null">plist_dict_merge
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libplist-plist_dict_merge/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_dict_merge/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_dict_merge/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
12.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.8</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.35</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libplist-plist_dict_merge/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libxml2
   </td>
   <td style="background-color: null">xmltextreaderschemavalidatectxt
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libxml2-xmltextreaderschemavalidatectxt/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidatectxt/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidatectxt/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.19</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.33</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libxml2-xmltextreaderschemavalidatectxt/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_printpreallocated
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_printpreallocated/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_printpreallocated/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_printpreallocated/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
75</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
26.44</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.22</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_printpreallocated/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libucl
   </td>
   <td style="background-color: null">ucl_parser_insert_chunk
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libucl-ucl_parser_insert_chunk/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_insert_chunk/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_insert_chunk/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
10.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.22</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_insert_chunk/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libucl
   </td>
   <td style="background-color: null">ucl_object_compare
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libucl-ucl_object_compare/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_compare/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_compare/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
12.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
1.35</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.21</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_compare/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">elfutils
   </td>
   <td style="background-color: null">dwarf_getlocations
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/elfutils-dwarf_getlocations/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwarf_getlocations/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwarf_getlocations/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
7.22</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.2</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=elfutils-dwarf_getlocations/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libucl
   </td>
   <td style="background-color: null">ucl_parser_add_fd_priority
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libucl-ucl_parser_add_fd_priority/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_add_fd_priority/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_add_fd_priority/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
71.43</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
19.61</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.18</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_parser_add_fd_priority/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">jsoncpp
   </td>
   <td style="background-color: null">json-value-resize
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/jsoncpp-json-value-resize/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-resize/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-resize/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
2.23</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.17</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-resize/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">mosquitto
   </td>
   <td style="background-color: null">mosquitto_topic_matches_sub2
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/mosquitto-mosquitto_topic_matches_sub2/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub2/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub2/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
87.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
28.28</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.16</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub2/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">xvid
   </td>
   <td style="background-color: null">xvid_encore
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/xvid-xvid_encore/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=xvid-xvid_encore/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=xvid-xvid_encore/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
31.25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.22</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.16</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=xvid-xvid_encore/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_parse
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_parse/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parse/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parse/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
75</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.72</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.13</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parse/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">cjson
   </td>
   <td style="background-color: null">cjson_parsewithlength
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/cjson-cjson_parsewithlength/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parsewithlength/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parsewithlength/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
25.72</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.13</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=cjson-cjson_parsewithlength/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">jsoncpp
   </td>
   <td style="background-color: null">json-value-removeindex
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/jsoncpp-json-value-removeindex/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-removeindex/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-removeindex/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
5.11</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.13</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=jsoncpp-json-value-removeindex/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libucl
   </td>
   <td style="background-color: null">ucl_object_merge
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libucl-ucl_object_merge/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_merge/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_merge/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.65</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.12</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_merge/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">speex
   </td>
   <td style="background-color: null">ogg_stream_pageout_fill
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/speex-ogg_stream_pageout_fill/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_pageout_fill/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_pageout_fill/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
6.25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.07</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=speex-ogg_stream_pageout_fill/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libsndfile
   </td>
   <td style="background-color: null">sf_command
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libsndfile-sf_command/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_command/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_command/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
25</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
3.41</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.06</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_command/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">mosquitto
   </td>
   <td style="background-color: null">mosquitto_topic_matches_sub
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/mosquitto-mosquitto_topic_matches_sub/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
62.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
4.03</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.05</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=mosquitto-mosquitto_topic_matches_sub/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libsndfile
   </td>
   <td style="background-color: null">sf_format_check
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libsndfile-sf_format_check/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_format_check/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_format_check/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
12.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.1</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.04</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libsndfile-sf_format_check/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libucl
   </td>
   <td style="background-color: null">ucl_object_replace_key
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libucl-ucl_object_replace_key/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_replace_key/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_replace_key/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
50</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
7.14</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.04</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libucl-ucl_object_replace_key/report/">Reports</a>
   </td>
  </tr>
  <tr>
   <td style="background-color: null">libdwarf
   </td>
   <td style="background-color: null">dwarf_find_die_given_sig8
   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/libdwarf-dwarf_find_die_given_sig8/prompts.txt">Prompt</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libdwarf-dwarf_find_die_given_sig8/fixes/">Fixes</a>;
<br>
<a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libdwarf-dwarf_find_die_given_sig8/targets/">Targets</a>.
   </td>
   <td style="background-color: null"><p style="text-align: right">
37.5</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
11.62</p>

   </td>
   <td style="background-color: null"><p style="text-align: right">
0.01</p>

   </td>
   <td style="background-color: null"><a href="https://storage.googleapis.com/oss-fuzz-llm-targets-public/index.html?prefix=libdwarf-dwarf_find_die_given_sig8/report/">Reports</a>
   </td>
  </tr>
</table>


<script>jtd.setTheme('wider');</script>

---

### Getting Started New Project Guide Bazel (`docs/getting-started/new-project-guide/bazel.md`)

---
layout: default
title: Integrating a Bazel project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 5
permalink: /getting-started/new-project-guide/bazel/
---

# Integrating a Bazel project
{: .no_toc}

- TOC
{:toc}
---

## Bazel projects

The process of integrating a project using the [Bazel](https://bazel.build/)
build system with OSS-Fuzz is very similar to the general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a Bazel project are outlined below.

## Fuzzing support in Bazel

For Bazel-based projects, we recommend using the
[`rules_fuzzing`](https://github.com/bazelbuild/rules_fuzzing) extension library
for defining fuzz tests. `rules_fuzzing` provides support for building and running
fuzz tests under
[multiple sanitizer and fuzzing engine configurations][rules-fuzzing-usage].
It also supports specifying corpora and dictionaries as part of the fuzz test
definition.

The fuzzing rules provide out-of-the-box support for building and packaging fuzz
test artifacts in the OSS-Fuzz format. Each `//path/to:fuzz_test` fuzz test
target automatically has a `//path/to:fuzz_test_oss_fuzz` packaging target that
(a) builds the fuzz test using the instrumentation and engine library specified
in the OSS-Fuzz environment variables, and (b) generates an archive containing
the binary and its associated artifacts (corpus, dictionary, etc.). Moreover,
OSS-Fuzz provides a standard tool to automatically process these targets,
substantially simplifying the `build.sh` script (see below).

[rules-fuzzing-usage]: https://github.com/bazelbuild/rules_fuzzing#using-the-rules-in-your-project

## Project files

This section explains how to integrate the fuzz tests written using the
`rules_fuzzing` library with OSS-Fuzz. You can also see a complete example in the
[`bazel-rules-fuzzing-test`](https://github.com/google/oss-fuzz/tree/master/projects/bazel-rules-fuzzing-test)
project.

The structure of the project directory in the OSS-Fuzz repository does not
differ for Bazel-based projects. The project files have the following specific
aspects.

### project.yaml

Only C++ projects are currently supported.

Since the OSS-Fuzz target builds the fuzz test using the instrumentation and
engine specified in the OSS-Fuzz environment variables, all the engine and
sanitizer configurations supported in the `project.yaml` file are automatically
supported by the fuzzing rules.

### Dockerfile

There is no need to install Bazel in your Docker image. The OSS-Fuzz builder
image provides the `bazel` executable through the
[Bazelisk](https://github.com/bazelbuild/bazelisk) launcher, which will fetch
and use the latest Bazel release. If your project requires a particular Bazel
version, create a
[`.bazelversion`](https://docs.bazel.build/versions/master/updating-bazel.html)
file in your repository root with the desired version string.

### build.sh

Your `build.sh` script essentially needs to perform three steps: (1) selecting
which fuzz tests to build, (2) building their OSS-Fuzz package targets in the
right configuration, and (3) copying the build artifacts to the `${OUT}/`
destination.

OSS-Fuzz provides a
[`bazel_build_fuzz_tests`](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/bazel_build_fuzz_tests)
tool that implements these steps in a standard way, so in most cases your
build script only needs to invoke this command with no arguments.

If necessary, the behavior of the tool can be customized through a set of
environment variables. The most common are:

* `BAZEL_EXTRA_BUILD_FLAGS` are extra build flags passed on the Bazel command
   line.
* `BAZEL_FUZZ_TEST_TAG` and `BAZEL_FUZZ_TEST_EXCLUDE_TAG` can be overridden to
  specify which target tags to use when determining what fuzz tests to include.
  By default, the tool selects all the fuzz tests except for those tagged as
  `"no-oss-fuzz"`.
* `BAZEL_FUZZ_TEST_QUERY` overrides the Bazel query the tool uses to identify
  the fuzz tests to build, if the tag-based approach is not sufficient.

---

### Getting Started New Project Guide Go Lang (`docs/getting-started/new-project-guide/go_lang.md`)

---
layout: default
title: Integrating a Go project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 1
permalink: /getting-started/new-project-guide/go-lang/
---

# Integrating a Go project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in Go with OSS-Fuzz is very similar
to the general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a Go project are outlined below.

## Go-fuzz support

OSS-Fuzz supports **go-fuzz** in the
[libFuzzer compatible mode](https://github.com/mdempsky/go114-fuzz-build)
only. In that mode, fuzz targets for Go use the libFuzzer engine with native Go
coverage instrumentation. Binaries compiled in this mode provide the same
libFuzzer command line interface as non-Go fuzz targets.

## Native Go Fuzzing support

OSS-fuzz supports [fuzzers written for the native Go 1.18 engine](https://go.dev/doc/fuzz/). These fuzzers are built as libFuzzer binaries in a similar fashion as fuzzers written for the go-fuzz engine. Because of that, dictionaries and seed corpora should be handled in accordance with [the OSS-fuzz documentation](https://google.github.io/oss-fuzz/getting-started/new-project-guide/#seed-corpus).
Unlike libFuzzer/go-fuzz targets which must accept one data buffer, fuzz targets written for the Native Go engine can accept any number of arguments of any type. Here is an example of a valid fuzzer with multiple arguments:

```go
package demofuzzing

import (
    "fmt"
    "testing"
)

func FuzzDemo(f *testing.F) {
    f.Fuzz(func(t *testing.T, data1 string, data2 uint32, data3 float64) {
        fmt.Println(data1)
        fmt.Println(data2)
        fmt.Println(data3)
    })
}
```

Some requirements for native Go 1.18 fuzzers are:
* The only `testing.F` method supported is currently `F.Fuzz()`.
* `F.Add()` will not add seeds when fuzzing. To provide OSS-fuzz with a seed corpus, follow the documentation [here](https://google.github.io/oss-fuzz/getting-started/new-project-guide/#seed-corpus).

## Project files

First, you need to write a Go fuzz target. This fuzz target should reside in your project
repository
([example](https://github.com/golang/go/blob/4ad13555184eb0697c2e92c64c1b0bdb287ccc10/src/html/fuzz.go#L13)).

The structure of the project directory in OSS-Fuzz repository doesn't differ for
projects written in Go. The project files have the following Go specific
aspects.

### project.yaml

The `language` attribute must be specified.

```yaml
language: go
```

The only supported fuzzing engine and sanitizer are `libfuzzer` and `address`,
respectively.
[Example](https://github.com/google/oss-fuzz/blob/356f2b947670b7eb33a1f535c71bc5c87a60b0d1/projects/syzkaller/project.yaml#L7):

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - address
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-go`

The OSS-Fuzz builder image has the latest stable release of Golang installed. In
order to install dependencies of your project, add `RUN git clone ...` command to
your Dockerfile.
[Example](https://github.com/google/oss-fuzz/blob/356f2b947670b7eb33a1f535c71bc5c87a60b0d1/projects/syzkaller/Dockerfile#L23):

```dockerfile
# Dependency for one of the fuzz targets.
RUN git clone --depth 1 https://github.com/ianlancetaylor/demangle
```

go-fuzz will then automatically download the dependencies based on the go.mod file

### build.sh

In order to build a Go fuzz target, you need to call `go-fuzz`
command first, and then link the resulting `.a` file against
`$LIB_FUZZING_ENGINE` using the `$CXX $CXXFLAGS ...` command.

For go-fuzz fuzzers, the best way to do this is by using the [`compile_go_fuzzer` script](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_go_fuzzer), and for native Go 1.18 fuzzers it is recommended to use the [`compile_native_go_fuzzer` script](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_native_go_fuzzer). Both of these also support coverage builds.

`compile_native_go_fuzzer` requires two dependencies which can be installed with:
```bash
go install github.com/AdamKorcz/go-118-fuzz-build@latest
go get github.com/AdamKorcz/go-118-fuzz-build/testing
```

A usage example from go-dns project is

```sh
compile_go_fuzzer github.com/miekg/dns FuzzNewRR fuzz_newrr fuzz
```

Arguments are :
* path of the package with the fuzz target
* name of the fuzz function
* name of the fuzzer to be built
* optional tag to be used by `go build` and such

---

### Getting Started New Project Guide Javascript Lang (`docs/getting-started/new-project-guide/javascript_lang.md`)

---
layout: default
title: Integrating a JavaScript project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 4
permalink: /getting-started/new-project-guide/javascript-lang/
---

# Integrating a JavaScript project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in JavaScript for Node.js 
with OSS-Fuzz is very similar to the general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a JavaScript project are outlined below.

## Jazzer.js

JavaScript fuzzing in OSS-Fuzz is powered by
[Jazzer.js](https://github.com/CodeIntelligenceTesting/jazzer.js), which is
installed during the build step. As Jazzer.js operates directly on the JavaScript
source code level, it can be applied to any project written in a language that 
can be transpiled into JavaScript such as TypeScript. More information on how Jazzer.js
fuzz targets look like can be found in its
[README's Usage section](https://github.com/CodeIntelligenceTesting/jazzer.js#usage).

## Project files

### Example project

We recommend viewing
[javascript-example](https://github.com/google/oss-fuzz/tree/master/projects/javascript-example)
as an example of a simple JavaScript fuzzing project. We also recommend having a look at
[typescript-example](https://github.com/google/oss-fuzz/tree/master/projects/typescript-example)
as an example of how to fuzz TypeScript projects. This example also demonstrates how to use 
Jazzer.js fuzzed data provider.

### project.yaml

The `language` attribute must be specified as follows:

```yaml
language: javascript
```

The only supported fuzzing engine is libFuzzer (`libfuzzer`). So far, native sanitizers such as 
AddressSanitizer (`address`) and UndefinedBehaviorSanitizer (`undefined`) are not supported. 
They would only be needed for projects that have native addons, which is a rather infrequent
use case for JavaScript projects. If you have a project where you need ASan or UBSan, please 
create open an issue on [Jazzer.js GitHub repo](https://github.com/CodeIntelligenceTesting/jazzer.js). None (`none`) is the default sanitizer for 
JavaScript projects, so setting it up in `project.yaml` is optional.

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - none
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-javascript`

The OSS-Fuzz base Docker images already come with Node.js 19 and `npm` pre-installed.
Apart from that, you should usually not need to do more than to clone the
project, set a `WORKDIR`, and copy any necessary files, or install any
project-specific dependencies here as you normally would.

### Fuzzers

In the simplest case, every fuzzer consists of a single JavaScript file that exports
a function named `fuzz` taking a single argument of type [Buffer](https://nodejs.org/api/buffer.html). 
An example fuzz target could thus be a file `fuzz_string_compare.js` with contents:

```javascript
/**
 * @param { Buffer } data
 */
module.exports.fuzz = function (data) {
    const s = data.toString();
    if (s.length !== 16) {
        return;
    }
    if (
        s.slice(0, 8) === "Awesome " &&
        s.slice(8, 15) === "Fuzzing" &&
        s[15] === "!"
    ) {
        throw Error("Welcome to Awesome Fuzzing!");
    }
};
```

### build.sh

The OSS-Fuzz base docker image for JavaScript comes with the [`compile_javascript_fuzzer` script](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_javascript_fuzzer) preinstalled. In `build.sh`, you should install dependencies for your project, and if necessary compile the code into JavaScript. Then, you can use the script to build the fuzzers. The script ensures that [@Jazzer.js/core](https://www.npmjs.com/package/@jazzer.js/core) is installed so that its CLI can be used to execute your fuzz tests. It also generates a wrapper script that can be used as a drop-in replacement for libFuzzer. This means that the generated script accepts the same command line flags for libFuzzer. Under the hood these flags are simply forwarded to the libFuzzer native addon used by Jazzer.js.

A usage example from the javascript-example project is

```shell
compile_javascript_fuzzer example fuzz_string_compare.js --sync
```

Arguments are:
* relative path of the project in the $SRC directory
* relative path to the fuzz test inside the project
* remaining arguments are forwarded to the [Jazzer.js CLI](https://github.com/CodeIntelligenceTesting/jazzer.js/blob/main/docs/fuzz-targets.md#running-the-fuzz-target)

The [javascript-example](https://github.com/google/oss-fuzz/blob/master/projects/javascript-example/build.sh)
project contains an example of a `build.sh` for JavaScript projects.

## FuzzedDataProvider

Jazzer.js provides a `FuzzedDataProvider` that can simplify the task of creating a
fuzz target by translating the raw input bytes received from the fuzzer into
useful primitive JavaScript types. Its functionality is similar to
`FuzzedDataProviders` available in other languages, such as
[Java](https://codeintelligencetesting.github.io/jazzer-docs/jazzer-api/com/code_intelligence/jazzer/api/FuzzedDataProvider.html) and
[C++](https://github.com/google/fuzzing/blob/master/docs/split-inputs.md).

A fuzz target using the `FuzzedDataProvider` would look as follows:

```javascript
const { FuzzedDataProvider } = require("@jazzer.js/core");

/**
 * @param { Buffer } fuzzerInputData
 */
module.exports.fuzz = function (fuzzerInputData) {
    const data = new FuzzedDataProvider(fuzzerInputData);
    const i = data.consumeIntegral(4);
    const s = data.consumeRemainingAsString();
    exploreMe(i, s);
};
```

---

### Getting Started New Project Guide Jvm Lang (`docs/getting-started/new-project-guide/jvm_lang.md`)

---
layout: default
title: Integrating a Java/JVM project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 4
permalink: /getting-started/new-project-guide/jvm-lang/
---

# Integrating a Java/JVM project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in Java or any other language
running on the Java Virtual Machine (JVM) with OSS-Fuzz is very similar to the
general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a JVM project are outlined below.

## Jazzer

Java fuzzing in OSS-Fuzz depends on
[Jazzer](https://github.com/CodeIntelligenceTesting/jazzer), which is
pre-installed on the OSS-Fuzz base docker images. As Jazzer operates directly
on the bytecode level, it can be applied to any project written in a JVM-based
language. More information on how Jazzer fuzz targets look like can be found in
its
[README's Usage section](https://github.com/CodeIntelligenceTesting/jazzer#usage).

## Project files

### Example project

We recommend viewing
[json-sanitizer](https://github.com/google/oss-fuzz/tree/master/projects/json-sanitizer)
as an example of a simple Java-only fuzzing project. Additional examples,
including one for a Java project with native dependencies, are part of the
[java-example](https://github.com/google/oss-fuzz/tree/master/projects/java-example)
project.

### project.yaml

The `language` attribute must be specified as follows:

```yaml
language: jvm
```

The only supported fuzzing engine is libFuzzer (`libfuzzer`). So far the only
supported sanitizers are AddressSanitizer (`address`) and
UndefinedBehaviorSanitizer (`undefined`). For pure Java projects, specify
just `address`:

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - address
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-jvm`

The OSS-Fuzz base Docker images already come with OpenJDK 15 pre-installed. If
you need Maven to build your project, you can install it by adding the following
line to your Dockerfile:

```docker
RUN apt-get update && apt-get install -y maven
```

Apart from this, you should usually not need to do more than to clone the
project, set a `WORKDIR`, and copy any necessary files, or install any
project-specific dependencies here as you normally would.

### Fuzzers

In the simplest case, every fuzzer consists of a single Java file with a
filename matching `*Fuzzer.java` and no `package` directive. An example fuzz
target could thus be a file `ExampleFuzzer.java` with contents:

```java
public class ExampleFuzzer {
    public static void fuzzerTestOneInput(byte[] input) {
        ...
        // Call a function of the project under test with arguments derived from
        // input and throw an exception if something unwanted happens.
        ...
    }
}
```

### build.sh

For JVM projects, `build.sh` does need some more significant modifications
over C/C++ projects. Below is an annotated example build script for a
Java-only project with single-file fuzz targets as described above:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The [java-example](https://github.com/google/oss-fuzz/blob/master/projects/java-example/build.sh)
project contains an example of a `build.sh` for Java projects with native
libraries.

## FuzzedDataProvider

Jazzer provides a `FuzzedDataProvider` that can simplify the task of creating a
fuzz target by translating the raw input bytes received from the fuzzer into
useful primitive Java types. Its functionality is similar to
`FuzzedDataProviders` available in other languages, such as
[Python](https://github.com/google/atheris#fuzzeddataprovider) and
[C++](https://github.com/google/fuzzing/blob/master/docs/split-inputs.md).

On OSS-Fuzz, the required library is available in the base docker images under
the path `$JAZZER_API_PATH`, which is added to the classpath by the example
build script shown above. Locally, the library can be obtained from
[Maven Central](https://search.maven.org/search?q=g:com.code-intelligence%20a:jazzer-api).

A fuzz target using the `FuzzedDataProvider` would look as follows:

```java
import com.code_intelligence.jazzer.api.FuzzedDataProvider;

public class ExampleFuzzer {
    public static void fuzzerTestOneInput(FuzzedDataProvider data) {
        int number = data.consumeInt();
        String string = data.consumeRemainingAsString();
        // ...
    }
}
```

For a list of convenience methods offered by `FuzzedDataProvider`, consult its
[javadocs](https://codeintelligencetesting.github.io/jazzer-docs/jazzer-api/com/code_intelligence/jazzer/api/FuzzedDataProvider.html).

---

### Getting Started New Project Guide Lua Lang (`docs/getting-started/new-project-guide/lua_lang.md`)

---
layout: default
title: Integrating a Lua project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 4
permalink: /getting-started/new-project-guide/lua-lang/
---

# Integrating a Lua project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in Lua with OSS-Fuzz
is similar to the general [Setting up a new project]({{ site.baseurl
}}/getting-started/new-project-guide/) process. The key specifics of
integrating a Lua project are outlined below.

## luzer

Lua fuzzing in OSS-Fuzz is powered by
[luzer](https://github.com/ligurio/luzer). As luzer operates
directly on the Lua source code level, it can be applied to any
project written in a language that can be transpiled into Lua,
such as [MoonScript](https://moonscript.org/),
[TypeScriptToLua](https://typescripttolua.github.io/),
[Fennel](https://fennel-lang.org/), and [Urn](https://urn-lang.com/).
Also, it supports fuzzing C/C++ extensions written for Lua. When
fuzzing native code, luzer can be used in combination with
Address Sanitizer or Undefined Behavior Sanitizer to catch extra bugs.

## Project files

### Example project

We recommend viewing
[lua-example](https://github.com/google/oss-fuzz/tree/master/projects/lua-example)
as an example of a simple Lua fuzzing project. This example also
demonstrates how to use luzer's Fuzzed Data Provider.

### project.yaml

The `language` attribute must be specified as follows:

```yaml
language: c
```

The only supported fuzzing engine is libFuzzer (`libfuzzer`).

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - none
```

There is nothing special for sanitizer support in OSS-Fuzz
infrastructure. luzer builds its own DSO with libFuzzer and
sanitizer and `compile_lua_fuzzer` (also managed by project) sets
it to `LD_PRELOAD` if required.

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder`.

The OSS-Fuzz base Docker images come without any pre-installed
components required for Lua fuzzing. Apart from that, you should
usually need to build or install a Lua runtime, luzer module,
clone the project, set a `WORKDIR`, and copy any necessary files,
or install any project-specific dependencies here as you normally would.

### Fuzzers

In the simplest case, every fuzzer consists of a single Lua file that defines
a function `TestOneInput` and executes a function named `luzer.Fuzz()`.
An example fuzz target could thus be a file `fuzz_basic.lua` with contents:

```lua
local parser = require("src.luacheck.parser")
local decoder = require("luacheck.decoder")
local luzer = require("luzer")

local function TestOneInput(buf)
    parser.parse(decoder.decode(buf))
end

local args = {
    print_final_stats = 1,
}
luzer.Fuzz(TestOneInput, nil, args)
```

### compile_lua_fuzzer

Unlike projects for other languages, the base image does not
include a script that generates a wrapper script that can be used
as a drop-in replacement for libFuzzer.

Therefore, you need to add such a script yourself. This script
sets a relative path to Lua runtime that will be used for running
tests and the necessary environment variables (for example, `LUA_PATH`,
`LUA_CPATH` and `LD_PRELOAD`) and specifies the path directly to
the `.lua` file containing the test implementation. The script
`compile_lua_fuzzer` must accept the same command line flags as
libFuzzer-based tests.

Note, the resulting wrapper scripts must contain the word "luarocks"
to pass checks by `bad_build_check` in continuous integration.

Then, you can use the script `compile_lua_fuzzer` to build the fuzzers.
A usage example from the `lua-example` project is

```shell
compile_lua_fuzzer lua fuzz_basic.lua
```

Arguments are:

* a relative path to a Lua runtime name
* a relative path to the fuzzing test inside the OSS Fuzz project directory

The `lua-example` projects includes an
[example](https://github.com/google/oss-fuzz/blob/master/projects/lua-example/compile_lua_fuzzer)
of such script.

### build.sh

The script is executed within the image built from your [Dockerfile](#Dockerfile).

In general, this script should do the following:

- Set up or build a Lua runtime.
- Set up or build required dependencies for your tests.
- Generate wrapper scripts for your tests using [compile_lua_fuzzer](#compile_lua_fuzzer).

Resulting binaries, tests and their wrapper scripts, and a
directory with Luarocks dependencies should be placed in `$OUT`.

Beware, when installing the luzer module, you need to set the
environment variable `OSS_FUZZ` to non-empty value, otherwise the
build may fail.

The [lua-example](https://github.com/google/oss-fuzz/blob/master/projects/lua-example/build.sh)
project contains an example of a `build.sh` for a Lua projects.

## FuzzedDataProvider

luzer provides a Fuzzed Data Provider that is helpful for splitting
a fuzz input into multiple parts of various Lua types. Its
functionality is similar to
[Fuzzed Data Provider](https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider)
available in LLVM. Learn about methods, provided by FDP in luzer,
in [documentation](https://github.com/ligurio/luzer/blob/master/docs/api.md#structure-aware-fuzzing).

A fuzz target using the `FuzzedDataProvider` would look as follows:

```lua
local luzer = require("luzer")

local function TestOneInput(buf)
    local fdp = luzer.FuzzedDataProvider(buf)
    local str = fdp:consume_string(4)

    local b = {}
    str:gsub(".", function(c) table.insert(b, c) end)
    local count = 0
    if b[1] == "o" then count = count + 1 end
    if b[2] == "o" then count = count + 1 end
    if b[3] == "p" then count = count + 1 end
    if b[4] == "s" then count = count + 1 end

    if count == 4 then assert(nil) end
end

local args = {
    only_ascii = 1,
    print_pcs = 1,
}

luzer.Fuzz(TestOneInput, nil, args)
```

---

### Getting Started New Project Guide Python Lang (`docs/getting-started/new-project-guide/python_lang.md`)

---
layout: default
title: Integrating a Python project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 3
permalink: /getting-started/new-project-guide/python-lang/
---

# Integrating a Python project
{: .no_toc}

- TOC
{:toc}
---


The process of integrating a project written in Python with OSS-Fuzz is very
similar to the general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a Python project are outlined below.

## Atheris

Python fuzzing in OSS-Fuzz depends on
[Atheris](https://github.com/google/atheris). Fuzzers will depend on the
`atheris` package, and dependencies are pre-installed on the OSS-Fuzz base
docker images.

## Project files

### Example project

We recommend viewing [ujson](https://github.com/google/oss-fuzz/tree/master/projects/ujson) as an
example of a simple Python fuzzing project, with both plain-Atheris and
Atheris + Hypothesis harnesses.

### project.yaml

The `language` attribute must be specified.

```yaml
language: python3
```

The only supported fuzzing engine is libFuzzer (`libfuzzer`). The supported
sanitizers are AddressSanitizer (`address`) and
UndefinedBehaviorSanitizer (`undefined`). These must be explicitly specified.

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - address
  - undefined
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-python`

Because most dependencies are already pre-installed on the images, no
significant changes are needed in the Dockerfile for Python fuzzing projects.
You should simply clone the project, set a `WORKDIR`, and copy any necessary
files, or install any project-specific dependencies here as you normally would.

### build.sh

For Python projects, `build.sh` does need some more significant modifications
over normal projects. The following is an annotated example build script,
explaining why each step is necessary and when they can be omitted.

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Hypothesis

Using [Hypothesis](https://hypothesis.readthedocs.io/), the Python library for
[property-based testing](https://hypothesis.works/articles/what-is-property-based-testing/),
makes it really easy to generate complex inputs - whether in traditional test suites
or [by using test functions as fuzz harnesses](https://hypothesis.readthedocs.io/en/latest/details.html#use-with-external-fuzzers).

> Property based testing is the construction of tests such that, when these tests are fuzzed,
  failures in the test reveal problems with the system under test that could not have been
  revealed by direct fuzzing of that system.

We recommend using the [`hypothesis write`](https://hypothesis.readthedocs.io/en/latest/ghostwriter.html)
command to generate a starter fuzz harness.  This "ghostwritten" code may be usable as-is,
or provide a useful template for writing more specific tests.

See [here for the core "strategies"](https://hypothesis.readthedocs.io/en/latest/data.html),
for arbitrary data, [here for Numpy + Pandas support](https://hypothesis.readthedocs.io/en/latest/numpy.html),
or [here for a variety of third-party extensions](https://hypothesis.readthedocs.io/en/latest/strategies.html)
supporting everything from protobufs, to jsonschemas, to networkx graphs or geojson
or valid Python source code.
Hypothesis' integrated test-case reduction also makes it trivial to report a canonical minimal
example for each distinct failure discovered while fuzzing - just run the test function!

To use Hypothesis in OSS-Fuzz, install it in your Dockerfile with

```shell
RUN pip3 install hypothesis
```

See [the `ujson` structured fuzzer](https://github.com/google/oss-fuzz/blob/master/projects/ujson/hypothesis_structured_fuzzer.py)
for an example "polyglot" which can either be run with `pytest` as a standard test function,
or run with OSS-Fuzz as a fuzz harness.

---

### Getting Started New Project Guide Rust Lang (`docs/getting-started/new-project-guide/rust_lang.md`)

---
layout: default
title: Integrating a Rust project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 2
permalink: /getting-started/new-project-guide/rust-lang/
---

# Integrating a Rust project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in Rust with OSS-Fuzz is very
similar to the general [Setting up a new project]({{ site.baseurl
}}/getting-started/new-project-guide/) process. The key specifics of integrating
a Rust project are outlined below.

## cargo-fuzz support

Rust integration with OSS-Fuzz is expected to use [`cargo
fuzz`](https://github.com/rust-fuzz/cargo-fuzz) to build fuzzers. The `cargo
fuzz` tool will build code with required compiler flags as well as link to the
correct libFuzzer on OSS-Fuzz itself. Note that using `cargo fuzz` also makes it
quite easy to run the fuzzers locally yourself if you get a failing test case!

## Project files

First you'll want to follow the [setup instructions for `cargo fuzz`
itself](https://rust-fuzz.github.io/book/). Afterwards your project should have:

* A top-level `fuzz` directory.
* A `fuzz/Cargo.toml` manifest which pulls in necessary dependencies to fuzz.
* Some `fuzz/fuzz_targets/*.rs` files which are the fuzz targets that will be
  compiled and run on OSS-Fuzz.

Note that you can customize this layout as well, but you'll need to edit some
the scripts below to integrate into OSS-Fuzz.

### project.yaml

The `language` attribute must be specified.

```yaml
language: rust
```

The only supported fuzzing engine and sanitizer are `libfuzzer` and `address`,
respectively.
[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/project.yaml#L3-L6)

```yaml
sanitizers:
  - address
fuzzing_engines:
  - libfuzzer
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-rust`

The OSS-Fuzz builder image has the latest nightly release of Rust as well as
`cargo fuzz` pre-installed and in `PATH`. In the `Dockerfile` for your project
all you'll need to do is fetch the latest copy of your code and install any
system dependencies necessary to build your project.
[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/Dockerfile#L18-L20)

```dockerfile
RUN git clone --depth 1 https://github.com/serde-rs/json json
```

### build.sh

Here it's expected that you'll build the fuzz targets for your project and then
copy the final binaries into the output directory.
[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/build.sh#L20):

```sh
cd $SRC/json
cargo fuzz build -O
cp fuzz/target/x86_64-unknown-linux-gnu/release/from_slice $OUT/
```

Note that you likely want to pass the `-O` flag to `cargo fuzz build` which
builds fuzzers in release mode. You may also want to pass the
`--debug-assertions` flag to enable more checks while fuzzing. In this example
the `from_slice` binary is the fuzz target.

With some bash-fu you can also automatically copy over all fuzz targets into
the output directory so when you add a fuzz target to your project it's
automatically integrated into OSS-Fuzz:

```sh
FUZZ_TARGET_OUTPUT_DIR=target/x86_64-unknown-linux-gnu/release
for f in fuzz/fuzz_targets/*.rs
do
    FUZZ_TARGET_NAME=$(basename ${f%.*})
    cp $FUZZ_TARGET_OUTPUT_DIR/$FUZZ_TARGET_NAME $OUT/
done
```

## Writing fuzzers using a test-style strategy

In Rust you will often have tests written in a way so they are only 
compiled into the final binary when build in test-mode. This is, achieved by
wrapping your test code in `cfg(test)`, e.g.
```rust
#[cfg(test)]
mod tests {
    use super::*;
    
    ...
```

Cargo-fuzz automatically enables the `fuzzing` feature, which means you can
follow a similar strategy to writing fuzzers as you do when writing tests.
Specifically, you can create modules wrapped in the `fuzzing` feature:
```rust
#[cfg(fuzzing)]
pub mod fuzz_logic {
    use super::*;

    ...
```
and then call the logic within `fuzz_logic` from your fuzzer. 

Furthermore, within your `.toml` files, you can then specify fuzzing-specific
dependencies by wrapping them as follows:
```
[target.'cfg(fuzzing)'.dependencies]
```
similar to how you wrap test-dependencies as follows:
```
[dev-dependencies]
```

Finally, you can also combine the testing logic you have and the fuzz logic. This
can be achieved simply by using 
```rust
#[cfg(any(test, fuzzing))]
```

A project that follows this structure is Linkerd2-proxy and the project files can be
seen [here](https://github.com/google/oss-fuzz/tree/master/projects/linkerd2-proxy).

---

### Getting Started New Project Guide Swift Lang (`docs/getting-started/new-project-guide/swift_lang.md`)

---
layout: default
title: Integrating a Swift project
parent: Setting up a new project
grand_parent: Getting started
nav_order: 1
permalink: /getting-started/new-project-guide/swift-lang/
---

# Integrating a Swift project
{: .no_toc}

- TOC
{:toc}
---

The process of integrating a project written in Swift with OSS-Fuzz is very similar
to the general
[Setting up a new project]({{ site.baseurl }}/getting-started/new-project-guide/)
process. The key specifics of integrating a Swift project are outlined below.

## Project files

First, you need to write a Swift fuzz target that accepts a stream of bytes and
calls the program API with that. This fuzz target should reside in your project
repository.

The structure of the project directory in OSS-Fuzz repository doesn't differ for
projects written in Swift. The project files have the following Swift specific
aspects.

### project.yaml

The `language` attribute must be specified.

```yaml
language: swift
```

The only supported fuzzing engine is `libfuzzer`.

The supported sanitizers are `address` and `thread`.

[Example](https://github.com/google/oss-fuzz/blob/2a15c3c88b21f4f1be2a7ff115f72bd7a08e34ac/projects/swift-nio/project.yaml#L9):

```yaml
fuzzing_engines:
  - libfuzzer
sanitizers:
  - address
  - thread
```

### Dockerfile

The Dockerfile should start by `FROM gcr.io/oss-fuzz-base/base-builder-swift`
instead of using the simple base-builder

### build.sh

A `precompile_swift` generates an environment variable `SWIFTFLAGS`
This can then be used in the building command such as `swift build -c release $SWIFTFLAGS`


A usage example from swift-protobuf project is

```sh
. precompile_swift
# build project
cd FuzzTesting
swift build -c debug $SWIFTFLAGS

(
cd .build/debug/
find . -maxdepth 1 -type f -name "*Fuzzer" -executable | while read i; do cp $i $OUT/"$i"-debug; done
)

```

---

--- METRICS ---
- Files Extracted: 59
- Estimated Token Budget: ~68210 tokens
- Canonical Reference: https://codewiki.google/github.com/google/oss-fuzz
