]> git.proxmox.com Git - libgit2.git/blob - docs/fuzzing.md
New upstream version 1.3.0+dfsg.1
[libgit2.git] / docs / fuzzing.md
1 # Fuzzing
2
3 libgit2 is currently using [libFuzzer](https://libfuzzer.info) to perform
4 automated fuzz testing. libFuzzer only works with clang.
5
6 ## Prerequisites for building fuzz targets:
7
8 1. All the prerequisites for [building libgit2](https://github.com/libgit2/libgit2).
9 2. A recent version of clang. 6.0 is preferred. [pre-build Debian/Ubuntu
10 packages](https://github.com/libgit2/libgit2)
11
12 ## Build
13
14 1. Create a build directory beneath the libgit2 source directory, and change
15 into it: `mkdir build && cd build`
16 2. 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).
20 3. 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.
25 4. Build libgit2: `cmake --build .`
26 5. Exit the cmake build environment: `cd ..`
27
28 ## Run the fuzz targets
29
30 1. `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolize
31 LSAN_OPTIONS=allocator_may_return_null=1
32 ASAN_OPTIONS=allocator_may_return_null=1 ./build/fuzzers/packfile_fuzzer
33 fuzzers/corpora/packfile/`
34
35 The `LSAN_OPTIONS` and `ASAN_OPTIONS` are there to allow `malloc(3)` to return
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
38 where libFuzzer will write the coverage report.
39
40 ## Get coverage
41
42 In order to get coverage information, you need to add the "-fcoverage-mapping"
43 and "-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
45 be overridden by setting the `LLVM_PROFILE_FILE="yourfile.profraw"` environment
46 variable).
47
48 1. `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.
51 2. `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.
54 3. `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
60 In order to ensure that there are no regresions, each fuzzer target can be run
61 in a standalone mode. This can be done by passing `-DUSE_STANDALONE_FUZZERS=ON`.
62 This makes it compatible with gcc. This does not use the fuzzing engine, but
63 just invokes every file in the chosen corpus.
64
65 In order to get full coverage, though, you might want to also enable one of the
66 sanitizers. 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).