Skip to content

Commit

Permalink
Fix Fuzzer Crash in ClusterFuzz Due to Missing Git Executable
Browse files Browse the repository at this point in the history
A Git executable is not globally available in the ClusterFuzz container
environment where OSS-Fuzz executes fuzz tests, causing an error in the fuzz
harnesses when GitPython attempts to initialize, crashing the tests before they
can run.

To avoid this issue, we bundle the `git` binary that is available in the OSS-Fuzz
build container with the fuzz harness via Pyinstaller's `--add-binary` flag in
`build.sh` and use GitPython's `git.refresh(<full-path-to-git-executable>)`
method inside a Pyinstaller runtime check to initialize GitPython with the
bundled Git executable when running from the bundled application.

In all other execution environments, we assume a `git` executable is available
globally.

Fixes:
- #1905
- google/oss-fuzz#10600
  • Loading branch information
DaveLak committed Apr 22, 2024
1 parent bc7bd22 commit f4b95cf
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
9 changes: 7 additions & 2 deletions fuzzing/fuzz-targets/fuzz_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@
import atheris
import sys
import io
import os
from configparser import MissingSectionHeaderError, ParsingError

with atheris.instrument_imports():
from git import GitConfigParser
import git


def TestOneInput(data):
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
git.refresh(path_to_bundled_git_binary)

sio = io.BytesIO(data)
sio.name = "/tmp/fuzzconfig.config"
git_config = GitConfigParser(sio)
git_config = git.GitConfigParser(sio)
try:
git_config.read()
except (MissingSectionHeaderError, ParsingError, UnicodeDecodeError):
Expand Down
11 changes: 7 additions & 4 deletions fuzzing/fuzz-targets/fuzz_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
import shutil

with atheris.instrument_imports():
from git.objects import Tree
from git.repo import Repo
import git


def TestOneInput(data):
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
git.refresh(path_to_bundled_git_binary)

fdp = atheris.FuzzedDataProvider(data)
git_dir = "/tmp/.git"
head_file = os.path.join(git_dir, "HEAD")
Expand All @@ -46,9 +49,9 @@ def TestOneInput(data):
os.mkdir(common_dir)
os.mkdir(objects_dir)

_repo = Repo("/tmp/")
_repo = git.Repo("/tmp/")

fuzz_tree = Tree(_repo, Tree.NULL_BIN_SHA, 0, "")
fuzz_tree = git.Tree(_repo, git.Tree.NULL_BIN_SHA, 0, "")
try:
fuzz_tree._deserialize(io.BytesIO(data))
except IndexError:
Expand Down
2 changes: 1 addition & 1 deletion fuzzing/oss-fuzz-scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ find "$SEED_DATA_DIR" \( -name '*_seed_corpus.zip' -o -name '*.options' -o -name

# Build fuzzers in $OUT.
find "$SRC/gitpython/fuzzing" -name 'fuzz_*.py' -print0 | while IFS= read -r -d '' fuzz_harness; do
compile_python_fuzzer "$fuzz_harness"
compile_python_fuzzer "$fuzz_harness" --add-binary="$(command -v git):."

common_base_dictionary_filename="$SEED_DATA_DIR/__base.dict"
if [[ -r "$common_base_dictionary_filename" ]]; then
Expand Down

0 comments on commit f4b95cf

Please sign in to comment.