]> git.proxmox.com Git - libgit2.git/blame - docs/fuzzing.md
Bump Standards-Version to 4.6.0 (no changes needed)
[libgit2.git] / docs / fuzzing.md
CommitLineData
ac3d33df
JK
1# Fuzzing
2
3libgit2 is currently using [libFuzzer](https://libfuzzer.info) to perform
4automated fuzz testing. libFuzzer only works with clang.
5
0c9c969a 6## Prerequisites for building fuzz targets:
ac3d33df
JK
7
81. All the prerequisites for [building libgit2](https://github.com/libgit2/libgit2).
92. A recent version of clang. 6.0 is preferred. [pre-build Debian/Ubuntu
10 packages](https://github.com/libgit2/libgit2)
11
12## Build
13
141. Create a build directory beneath the libgit2 source directory, and change
15 into it: `mkdir build && cd build`
162. Choose one sanitizers to add. The currently supported sanitizers are
17 [`address`](https://clang.llvm.org/docs/AddressSanitizer.html),
18 [`undefined`](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
19 and [`leak`/`address,leak`](https://clang.llvm.org/docs/LeakSanitizer.html).
203. Create the cmake build environment and configure the build with the
21 sanitizer chosen: `CC=/usr/bin/clang-6.0 CFLAGS="-fsanitize=address" cmake
22 -DBUILD_CLAR=OFF -DBUILD_FUZZERS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..`.
23 Note that building the fuzzer targets is incompatible with the
24 tests and examples.
254. Build libgit2: `cmake --build .`
265. Exit the cmake build environment: `cd ..`
27
28## Run the fuzz targets
29
0c9c969a 301. `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolize
ac3d33df 31 LSAN_OPTIONS=allocator_may_return_null=1
0c9c969a
UG
32 ASAN_OPTIONS=allocator_may_return_null=1 ./build/fuzzers/packfile_fuzzer
33 fuzzers/corpora/packfile/`
ac3d33df
JK
34
35The `LSAN_OPTIONS` and `ASAN_OPTIONS` are there to allow `malloc(3)` to return
0c9c969a
UG
36`NULL`, which is expected if a huge chunk of memory is allocated. The
37`LLVM_PROFILE_FILE` environment string can also be added to override the path
38where libFuzzer will write the coverage report.
ac3d33df
JK
39
40## Get coverage
41
42In order to get coverage information, you need to add the "-fcoverage-mapping"
43and "-fprofile-instr-generate CFLAGS, and then run the fuzz target with
44`-runs=0`. That will produce a file called `default.profraw` (this behavior can
45be overridden by setting the `LLVM_PROFILE_FILE="yourfile.profraw"` environment
46variable).
47
481. `llvm-profdata-6.0 merge -sparse default.profraw -o
49 fuzz_packfile_raw.profdata` transforms the data from a sparse representation
50 into a format that can be used by the other tools.
512. `llvm-cov-6.0 report ./build/fuzz/fuzz_packfile_raw
52 -instr-profile=fuzz_packfile_raw.profdata` shows a high-level per-file
53 coverage report.
543. `llvm-cov-6.0 show ./build/fuzz/fuzz_packfile_raw
55 -instr-profile=fuzz_packfile_raw.profdata [source file]` shows a line-by-line
56 coverage analysis of all the codebase (or a single source file).
57
58## Standalone mode
59
60In order to ensure that there are no regresions, each fuzzer target can be run
61in a standalone mode. This can be done by passing `-DUSE_STANDALONE_FUZZERS=ON`.
62This makes it compatible with gcc. This does not use the fuzzing engine, but
63just invokes every file in the chosen corpus.
64
65In order to get full coverage, though, you might want to also enable one of the
66sanitizers. You might need a recent version of clang to get full support.
67
68## References
69
70* [libFuzzer](https://llvm.org/docs/LibFuzzer.html) documentation.
71* [Source-based Code
72 Coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html).