| Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame^] | 1 | =============================== | 
|  | 2 | Fuzzer -- a library for coverage-guided fuzz testing. | 
|  | 3 | =============================== | 
|  | 4 |  | 
|  | 5 | This library is intended primarily for in-process coverage-guided fuzz testing | 
|  | 6 | (fuzzing) of other libraries. The typical workflow looks like this: | 
|  | 7 |  | 
|  | 8 | * Build the Fuzzer library as a static archive (or just a set of .o files). | 
|  | 9 | Note that the Fuzzer contains the main() function. | 
|  | 10 | Preferably do *not* use sanitizers while building the Fuzzer. | 
|  | 11 | * Build the library you are going to test with -fsanitize-coverage=[234] | 
|  | 12 | and one of the sanitizers. We recommend to build the library in several | 
|  | 13 | different modes (e.g. asan, msan, lsan, ubsan, etc) and even using different | 
|  | 14 | optimizations options (e.g. -O0, -O1, -O2) to diversify testing. | 
|  | 15 | * Build a test driver using the same options as the library. | 
|  | 16 | The test driver is a C/C++ file containing interesting calls to the library | 
|  | 17 | inside a single function: | 
|  | 18 | extern "C" void TestOneInput(const uint8_t *Data, size_t Size); | 
|  | 19 | * Link the Fuzzer, the library and the driver together into an executable | 
|  | 20 | using the same sanitizer options as for the library. | 
|  | 21 | * Collect the initial corpus of inputs for the | 
|  | 22 | fuzzer (a directory with test inputs, one file per input). | 
|  | 23 | The better your inputs are the faster you will find something interesting. | 
|  | 24 | Also try to keep your inputs small, otherwise the Fuzzer will run too slow. | 
|  | 25 | * Run the fuzzer with the test corpus. As new interesting test cases are | 
|  | 26 | discovered they will be added to the corpus. If a bug is discovered by | 
|  | 27 | the sanitizer (asan, etc) it will be reported as usual and the reproducer | 
|  | 28 | will be written to disk. | 
|  | 29 | Each Fuzzer process is single-threaded (unless the library starts its own | 
|  | 30 | threads). You can run the Fuzzer on the same corpus in multiple processes. | 
|  | 31 | in parallel. For run-time options run the Fuzzer binary with '-help=1'. | 
|  | 32 |  | 
|  | 33 |  | 
|  | 34 | The Fuzzer is similar in concept to AFL (http://lcamtuf.coredump.cx/afl/), | 
|  | 35 | but uses in-process Fuzzing, which is more fragile, more restrictive, but | 
|  | 36 | potentially much faster as it has no overhead for process start-up. | 
|  | 37 | It uses LLVM's "Sanitizer Coverage" instrumentation to get in-process | 
|  | 38 | coverage-feedback https://code.google.com/p/address-sanitizer/wiki/AsanCoverage | 
|  | 39 |  | 
|  | 40 | The code resides in the LLVM repository and is (or will be) used by various | 
|  | 41 | parts of LLVM, but the Fuzzer itself does not (and should not) depend on any | 
|  | 42 | part of LLVM and can be used for other projects. Ideally, the Fuzzer's code | 
|  | 43 | should not have any external dependencies. Right now it uses STL, which may need | 
|  | 44 | to be fixed later. | 
|  | 45 |  | 
|  | 46 | Examples of usage in LLVM: | 
|  | 47 | * clang-format-fuzzer. The inputs are random pieces of C++-like text. | 
|  | 48 | * Build (make sure to use fresh clang as the host compiler): | 
|  | 49 | cmake -GNinja  -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ | 
|  | 50 | -DLLVM_USE_SANITIZER=Address -DLLVM_USE_SANITIZE_COVERAGE=YES \ | 
|  | 51 | /path/to/llvm -DCMAKE_BUILD_TYPE=Release | 
|  | 52 | ninja clang-format-fuzzer | 
|  | 53 | * Optionally build other kinds of binaries (asan+Debug, msan, ubsan, etc) | 
|  | 54 | * TODO: commit the pre-fuzzed corpus to svn (?). | 
|  | 55 | * Run: | 
|  | 56 | clang-format-fuzzer CORPUS_DIR | 
|  | 57 |  | 
|  | 58 | Toy example (see SimpleTest.cpp): | 
|  | 59 | a simple function that does something interesting if it receives bytes "Hi!". | 
|  | 60 | # Build the Fuzzer with asan: | 
|  | 61 | % clang++ -std=c++11 -fsanitize=address -fsanitize-coverage=3 -O1 -g \ | 
|  | 62 | Fuzzer*.cpp test/SimpleTest.cpp | 
|  | 63 | # Run the fuzzer with no corpus (assuming on empty input) | 
|  | 64 | % ./a.out |