Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions infra/experimental/agent-skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OSS-Fuzz agent skills

Skills that can be easily used with agents e.g. gemini CLI.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: fuzzing-memory-unsafe-expert
description:
Use this skill to fuzz open source C/C++ software projects.
---

# Fuzzing memory-unsafe expert

This skill provides the agent with the necessary knowledge and tools to fuzz open source software projects, particularly those that are part of the OSS-Fuzz program. The agent can use this skill to build fuzzers, run fuzzing campaigns, analyze results, and improve the fuzzing posture of projects.

The fuzzing abilities focused on here is libFuzzer-style harnesses, which are commonly used in OSS-Fuzz.

## Fundamental Concepts

### Fuzzing harness core function

A fuzzing harness is a function that takes a byte array as input and processes it in a way that can trigger bugs or vulnerabilities in the software being tested. The core function of a fuzzing harness typically looks like this:

```cpp
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Process the input data and trigger potential bugs
return 0; // Return 0 to indicate successful processing
}
```

### Characteristics found in good fuzzing harnesses

The below are characteristics commonly found in good fuzzing harnesses, which contribute to their effectiveness in finding bugs. They are not all necessary for a good harness and at times it may even be desirable to actively not pursue some of them.

1. **Simplicity**: The harness should be simple and focused on processing the input data without unnecessary complexity.
2. **Coverage**: The harness should aim to cover as much of the codebase as possible, including edge cases and error handling paths.
3. **Determinism**: The harness should produce consistent results for the same input, allowing for reliable reproduction of bugs.
4. **Performance**: The harness should be efficient in processing inputs to maximize the number of test cases that can be executed in a given time frame.
5. **Error Handling**: The harness should include robust error handling to capture and report any issues that arise during fuzzing.
6. **True Positives**: The harness should be designed to have no false positives, ensuring that reported issues are genuine bugs. This means all issues found by the fuzzer is something the maintainers are interested in fixing.
7. **Matches threat model**: The harness should be designed to target specific types of vulnerabilities that are relevant to the project being fuzzed.
8. **Hits code on the attack surface**: The harness should be designed to target code that is exposed to untrusted input, such as network interfaces, file parsers, or APIs.
9. **Enough entropy**: The harness should be designed to allow for a wide range of inputs, providing enough variability to trigger different code paths and potential bugs.
10. **Follows the code structure**: The harness should be designed to follow the structure of the codebase, making it easier to identify and target specific areas of interest.
11. **Follows code conventions**: The harness should follow the coding conventions of the project, making it easier for maintainers to understand and integrate the harness into the codebase.
12. **Does not get stuck**: The harness should be designed to avoid getting stuck on certain inputs or code paths, allowing the fuzzer to continue exploring other areas of the codebase.
13. **Includes dictionary**: The harness should include a dictionary of known inputs or patterns that are relevant to the project, helping the fuzzer to generate more effective test cases.
64 changes: 64 additions & 0 deletions infra/experimental/agent-skills/oss-fuzz-engineer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: oss-fuzz-engineer
description:
Use this skill to interact with the OSS-Fuzz infrastructure.
---

# OSS-Fuzz engineer

This skill guides the agent how to use the OSS-Fuzz infrastructure to find and report bugs in open source software. The agent can use this skill to integrate new projects, extend and improve the fuzzing posture of projects, run fuzzing campaigns, and fix broken existing OSS-Fuzz projects.

## Workflows

There are multiple common workflows that an OSS-Fuzz engineer might follow and we describe some imporant ones here.

### Integrating a new project

Given a reference to an open source project, such as a link to a GitHub repository, the agent can follow these steps to integrate the project into OSS-Fuzz:
1. **Assess the project**: The agent should first assess whether the project is suitable for fuzzing. This includes checking if the project is open source, has a significant user base, and contains code that can be fuzzed (e.g., C/C++ code).
2. **Set up the environment**: The agent should set up the necessary environment for fuzzing the project. This includes:
- A Dockerfile that defines the build environment for the project, using the OSS-Fuzz base images.
- A build script that compiles the project with the necessary instrumentation for fuzzing.
- A project.yaml that provides the necessary OSS-Fuzz meta data.
3. **Write fuzz targets**: The agent should write fuzz targets for the project. Fuzz targets are small programs that call into the project's code and are used by the fuzzing engine to generate inputs and find bugs.
4. **Test the integration**: The agent should test the integration by running the fuzz targets locally and ensuring that they work correctly. This project should be continue until the fuzz targets build and run well, and the OSS-Fuzz `check_build` script passes without errors.
5. **Conclude the integration**: Once the integration is complete, the agent should conclude with a message of the results achieved and the next steps the security engineer guiding the agent should take. The agent should *not* make any commits or push anything to GitHub, but should conclude on the work for the security engineer to review. The agent should never submit any changes to OSS-Fuzz's Github.

When doing this type of work it's crucial the agent uses any skills it has related to code analysis and fuzzing harness writing.

### Extending and improving fuzzing posture

The agent can also be used to extend and improve the fuzzing posture of existing OSS-Fuzz projects. This can include:
- Adding new fuzz targets to cover more code paths and functionality.
- Improving existing fuzz targets to make them more effective at finding bugs.
- Updating the build environment to include new dependencies or tools that can enhance fuzzing.
- Analyzing fuzzing results and identifying areas of the code that are not well covered by existing fuzz targets, and then writing new fuzz targets to cover those areas.

A useful approach for extending a project is to study the latest code coverage report for the project, which is publicly available, to identify areas of the code that are not well covered by existing fuzz targets. The agent can then write new fuzz targets to cover those areas, and test them locally before concluding on the work for the security engineer to review.

Use the local code coverage feature of the `python3 infra/helper.py` tool to generate code coverage reports for fuzz targets locally, for example to validate the code coverage achieved by a new fuzz target. This can be done by running `python3 infra/helper.py introspector --coverage-only PROJECT_NAME` and then studying the generated report in e.g. build/out/PROJECT_NAME/report.

The user may provide directions on how to extend the fuzzing, and it's crucial to follow instructions on this matter. For example, the user may ask to focus on a specific area of the code, or to target specific types of vulnerabilities. The agent should always provide a clear explanation of the rationale for each extension or improvement made to the fuzzing posture of the project.

When extending an OSS-Fuzz project it's crucial to have a good understanding of the target code. To this end, it's often useful to get a local version of the target source code into the OSS-Fuzz project structure to make working with the target project easy. This involves e.g. studying the `Dockerfile` of the target project, finding the e.g. `git clone` of the target project, and then cloning this repository locally and using e.g. `COPY` instead of `RUN git clone` in the Dockerfile to get the source code into the container.

The agent should always provide clear technical justification for each extension.

When doing this type of work it's crucial the agent uses any skills it has related to code analysis and fuzzing harness writing. It's important each extension is done through a personal assessment of the current fuzzing posture of the project, and a clear explanation of the rationale for each extension or improvement. The agent should never make any commits or push anything to GitHub, but should conclude on the work for the security engineer to review. The agent should never submit any changes to OSS-Fuzz's Github.


### Fixing broken existing OSS-Fuzz projects

The agent can also be used to fix broken existing OSS-Fuzz projects. This can include:
- Identifying and fixing build issues that prevent fuzz targets from running correctly.
- Updating dependencies or build scripts to ensure that the project can be fuzzed effectively.
- Analyzing fuzzing results to identify and fix issues that are causing the fuzzing campaign to fail or produce unreliable results.

A given OSS-Fuzz project must succeed with:

```
python3 infra/helper.py build_fuzzers PROJECT_NAME
python3 infra/helper.py check_build PROJECT_NAME
```

The agent should never make any commits or push anything to GitHub, but should conclude on the work for the security engineer to review. The agent should never submit any changes to OSS-Fuzz's Github.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# OSS-Fuzz latest code coverage

OSS-Fuzz makes code coverage reports publicly available. These
are available at URLS:

https://storage.googleapis.com/oss-fuzz-coverage/$PROJECT_NAME/reports/$DATE/linux/report.html


Where $PROJECT_NAME is the relevant OSS-Fuzz project and $DATE is the date of the coverage report.

For example, the URL https://storage.googleapis.com/oss-fuzz-coverage/gpsd/reports/20260123/linux/report.html holds the coverage report for the `gpsd` project for the 23rd January 2026.

There may not be a coverage report for a given date if the coverage build failed for the project on that date.

There is also structured information in the form of a .json file, on e.g. https://storage.googleapis.com/oss-fuzz-coverage/gpsd/reports/20260123/linux/summary.json

The OSS-Fuzz coverage reports are crucial for working on expanding OSS-Fuzz projects.

These coverage reports hold the data of the collective corpus collected by OSS-Fuzz for all the fuzzing harnesses in a given project.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# OSS-Fuzz Helper CLI Reference (`infra/helper.py`)

This document provides a reference for the `python3 infra/helper.py` command-line interface, which is the primary tool for interacting with OSS-Fuzz projects locally.

## Global Subcommands

### `generate`
Generate files for a new project.
```bash
python3 infra/helper.py generate [--language {c,c++,go,javascript,jvm,python,ruby,rust,swift}] [--external] <project>
```
- `--language`: Specify the project language.
- `--external`: Indicate if the project is external.

### `build_image`
Build a project's Docker image.
```bash
python3 infra/helper.py build_image [--pull] [--no-pull] [--architecture {i386,x86_64,aarch64}] [--cache] [--external] <project>
```
- `--pull`: Pull the latest base image before building.
- `--no-pull`: Do not pull the latest base image.
- `--cache`: Use Docker cache when building the image.

You should *always* use `--pull` unless explicitly asked not to.

### `build_fuzzers`
Build fuzzers for a project.
```bash
python3 infra/helper.py build_fuzzers [--architecture ARCH] [--engine ENGINE] [--sanitizer SANITIZER] [-e VAR=val] [--clean] [--no-clean] <project> [source_path]
```
- `--architecture`: Target architecture (default: `x86_64`).
- `--engine`: Fuzzing engine (default: `libfuzzer`).
- `--sanitizer`: Sanitizer to use (default: `address`). Options: `address`, `memory`, `undefined`, `thread`, `coverage`, `introspector`, `hwaddress`.
- `-e`: Set environment variables in the build container.
- `--clean`: Clean existing artifacts before building.
- `source_path`: Optional path to local source code to mount into the container.

In the vast majority of cases you should simple use `python3 infra/helper.py build_fuzzers PROJECT_NAME` without any options.

### `check_build`
Verify that built fuzzers execute without errors (checks if they can run for a few seconds).
```bash
python3 infra/helper.py check_build [--architecture ARCH] [--engine ENGINE] [--sanitizer SANITIZER] <project> [fuzzer_name]
```

### `run_fuzzer`
Run a specific fuzzer in the emulated fuzzing environment.
```bash
python3 infra/helper.py run_fuzzer [--architecture ARCH] [--engine ENGINE] [--sanitizer SANITIZER] [--corpus-dir CORPUS_DIR] <project> <fuzzer_name> [fuzzer_args ...]
```
- `fuzzer_args`: Arguments passed directly to the fuzzing engine (e.g., `-max_total_time=60`, `-runs=100`).

### `coverage`
Generate a code coverage report for the project.
```bash
python3 infra/helper.py coverage [--no-corpus-download] [--no-serve] [--port PORT] [--fuzz-target FUZZ_TARGET] <project> [extra_args ...]
```
- `--no-corpus-download`: Use local corpus instead of downloading from OSS-Fuzz.
- `--fuzz-target`: Specify a specific fuzz target to generate coverage for.
- `--no-serve`: Do not start a local web server to view the report.

### `reproduce`
Reproduce a crash using a local testcase.
```bash
python3 infra/helper.py reproduce [--valgrind] <project> <fuzzer_name> <testcase_path> [fuzzer_args ...]
```
- `testcase_path`: Path to the file containing the input that caused the crash.

### `shell`
Start an interactive shell within the project's builder container.
```bash
python3 infra/helper.py shell [--architecture ARCH] [--engine ENGINE] [--sanitizer SANITIZER] <project> [source_path]
```
- Useful for debugging build issues manually.

### `pull_images`
Pull the latest OSS-Fuzz base images.
```bash
python3 infra/helper.py pull_images
```

## Common Options
Most subcommands support:
- `--architecture`: `{i386,x86_64,aarch64}`
- `--engine`: `{libfuzzer,afl,honggfuzz,centipede,none,wycheproof}`
- `--sanitizer`: `{address,none,memory,undefined,thread,coverage,introspector,hwaddress}`
- `--external`: If the project is not in the `projects/` directory.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# OSS-Fuzz Project Structure

A project in OSS-Fuzz is defined by a directory in the `projects/` folder. This directory contains the necessary configuration and build scripts to integrate the project into the OSS-Fuzz infrastructure.

The core files required for an OSS-Fuzz project are:

## 1. `project.yaml`

This file contains metadata about the project. It is used by OSS-Fuzz to manage the project, contact maintainers, and define the fuzzing configuration.

Key fields include:
- `homepage`: The project's official website.
- `language`: The primary programming language of the project (e.g., `c++`, `go`, `rust`, `python`, `java`).
- `primary_contact`: The email address of the main person responsible for the project's integration.
- `auto_ccs`: A list of additional email addresses to be notified of issues.
- `fuzzing_engines`: The fuzzing engines to use (e.g., `libfuzzer`, `afl`, `honggfuzz`).
- `sanitizers`: The sanitizers to use (e.g., `address`, `undefined`, `memory`).
- `main_repo`: The URL of the project's source code repository.
- `base_os_version`: set to ubuntu-24-04 if base builder image used is ubuntu-24-04

## 2. `Dockerfile`

The `Dockerfile` defines the build environment for the project. It must inherit from an OSS-Fuzz base image, typically `gcr.io/oss-fuzz-base/base-builder`.

Its responsibilities include:
- Installing any necessary build dependencies (via `apt-get`).
- Checking out the project's source code (e.g., via `git clone`).
- Copying the `build.sh` script and any other necessary files into the container.
- Setting the working directory to the project's source code.

Example snippet:
```dockerfile
FROM gcr.io/oss-fuzz-base/base-builder:ubuntu-24-04
RUN apt-get update && apt-get install -y make autoconf automake libtool
RUN git clone --depth 1 https://github.com/example/project.git
WORKDIR project
COPY build.sh $SRC/
```

## 3. `build.sh`

The `build.sh` script is responsible for compiling the project and its fuzz targets. It is executed inside the Docker container defined by the `Dockerfile`.

It should use environment variables provided by OSS-Fuzz:
- `$CC`, `$CXX`, `$CFLAGS`, `$CXXFLAGS`: Compilers and flags for instrumentation.
- `$OUT`: The directory where the resulting fuzzer binaries and other artifacts (like seed corpora or dictionary files) should be placed.
- `$SRC`: points to /src in the container
- `$LIB_FUZZING_ENGINE`: The library to link against for the chosen fuzzing engine.

The script typically performs the following steps:
1. Build the project's libraries using the provided compilers and flags.
2. Compile the fuzz targets and link them against the project's libraries and `$LIB_FUZZING_ENGINE`.
3. Copy the fuzzer binaries to `$OUT`.
4. (Optional) Create and copy seed corpora (as `.zip` files) and dictionaries (as `.dict` files) to `$OUT`.

Example snippet:
```bash
# Build the project
./autogen.sh
./configure
make -j$(nproc)

# Build a fuzzer
$CXX $CXXFLAGS -Iinclude \
/path/to/fuzzer.cc -o $OUT/my_fuzzer \
$LIB_FUZZING_ENGINE /path/to/library.a
```
Loading