Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerize "Direct Execution of Fuzz Targets" #1904

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 37 additions & 6 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ capabilities, jump into the "Getting Started" section below.
### Setting Up Your Local Environment

Before contributing to fuzzing efforts, ensure Python and Docker are installed on your machine. Docker is required for
running fuzzers in containers provided by OSS-Fuzz. [Install Docker](https://docs.docker.com/get-docker/) following the
official guide if you do not already have it.
running fuzzers in containers provided by OSS-Fuzz and for safely executing test files directly. [Install Docker](https://docs.docker.com/get-docker/) following the official guide if you do not already have it.

### Understanding Existing Fuzz Targets

Expand Down Expand Up @@ -110,19 +109,51 @@ Includes scripts for building and integrating fuzz targets with OSS-Fuzz:
- [OSS-Fuzz documentation on the build.sh](https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh)
- [See GitPython's build.sh and Dockerfile in the OSS-Fuzz repository](https://github.com/google/oss-fuzz/tree/master/projects/gitpython)

### Local Development Helpers (`local-dev-helpers/`)

Contains tools to make local development tasks easier.
See [the "Running Fuzzers Locally" section below](#running-fuzzers-locally) for further documentation and use cases related to files found here.

## Running Fuzzers Locally

> [!WARNING]
> **Some fuzz targets in this repository write to the filesystem** during execution.
> For that reason, it is strongly recommended to **always use Docker when executing fuzz targets**, even when it may be
> possible to do so without it.
>
> Although [I/O operations such as writing to disk are not considered best practice](https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md#io), the current implementation of at least one test requires it.
> See [the "Setting Up Your Local Environment" section above](#setting-up-your-local-environment) if you do not already have Docker installed on your machine.
>
> PRs that replace disk I/O with in-memory alternatives are very much welcomed!

### Direct Execution of Fuzz Targets

For quick testing of changes, [Atheris][atheris-repo] makes it possible to execute a fuzz target directly:
Directly executing fuzz targets allows for quick iteration and testing of changes which can be helpful during early
development of new fuzz targets or for validating changes made to an existing test.
The [Dockerfile](./local-dev-helpers/Dockerfile) located in the `local-dev-helpers/` subdirectory provides a lightweight
container environment preconfigured with [Atheris][atheris-repo] that makes it easy to execute a fuzz target directly.

**From the root directory of your GitPython repository clone**:

1. Install Atheris following the [installation guide][atheris-repo] for your operating system.
2. Execute a fuzz target, for example:
1. Build the local development helper image:

```shell
python fuzzing/fuzz-targets/fuzz_config.py
docker build -f fuzzing/local-dev-helpers/Dockerfile -t gitpython-fuzzdev .
```

2. Then execute a fuzz target inside the image, for example:

```shell
docker run -it -v "$PWD":/src gitpython-fuzzdev python fuzzing/fuzz-targets/fuzz_config.py -atheris_runs=10000
```

The above command executes [`fuzz_config.py`](./fuzz-targets/fuzz_config.py) and exits after `10000` runs, or earlier if
the fuzzer finds an error.

Docker CLI's `-v` flag specifies a volume mount in Docker that maps the directory in which the command is run (which
should be the root directory of your local GitPython clone) to a directory inside the container, so any modifications
made between invocations will be reflected immediately without the need to rebuild the image each time.

### Running OSS-Fuzz Locally

This approach uses Docker images provided by OSS-Fuzz for building and running fuzz tests locally. It offers
Expand Down
22 changes: 22 additions & 0 deletions fuzzing/local-dev-helpers/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# syntax=docker/dockerfile:1

# Use the same Python version as OSS-Fuzz to accidental incompatibilities in test code
FROM python:3.8-slim

LABEL project="GitPython Fuzzing Local Dev Helper"

WORKDIR /src

COPY . .

# Update package managers, install necessary packages, and cleanup unnecessary files in a single RUN to keep the image smaller.
RUN apt-get update && \
apt-get install --no-install-recommends -y git && \
python -m pip install --upgrade pip && \
python -m pip install atheris && \
python -m pip install -e . && \
apt-get clean && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/* /root/.cache

CMD ["bash"]