149 lines · plain
1This directory contains three utilities for fuzzing Clang: clang-fuzzer,2clang-objc-fuzzer, and clang-proto-fuzzer. All use libFuzzer to generate inputs3to clang via coverage-guided mutation.4 5The three utilities differ, however, in how they structure inputs to Clang.6clang-fuzzer makes no attempt to generate valid C++ programs and is therefore7primarily useful for stressing the surface layers of Clang (i.e. lexer, parser).8 9clang-objc-fuzzer is similar but for Objective-C: it makes no attempt to10generate a valid Objective-C program.11 12clang-proto-fuzzer uses a protobuf class to describe a subset of the C++13language and then uses libprotobuf-mutator to mutate instantiations of that14class, producing valid C++ programs in the process. As a result,15clang-proto-fuzzer is better at stressing deeper layers of Clang and LLVM.16 17Some of the fuzzers have example corpuses inside the corpus_examples directory.18 19===================================20 Building clang-fuzzer21===================================22Within your LLVM build directory, run CMake with the following variable23definitions:24- CMAKE_C_COMPILER=clang25- CMAKE_CXX_COMPILER=clang++26- LLVM_USE_SANITIZE_COVERAGE=YES27- LLVM_USE_SANITIZER=Address28 29Then build the clang-fuzzer target.30 31Example:32 cd $LLVM_SOURCE_DIR33 mkdir build && cd build34 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \35 -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address36 ninja clang-fuzzer37 38======================39 Running clang-fuzzer40======================41 bin/clang-fuzzer CORPUS_DIR42 43 44===================================45 Building clang-objc-fuzzer46===================================47Within your LLVM build directory, run CMake with the following variable48definitions:49- CMAKE_C_COMPILER=clang50- CMAKE_CXX_COMPILER=clang++51- LLVM_USE_SANITIZE_COVERAGE=YES52- LLVM_USE_SANITIZER=Address53 54Then build the clang-objc-fuzzer target.55 56Example:57 cd $LLVM_SOURCE_DIR58 mkdir build && cd build59 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \60 -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address61 ninja clang-objc-fuzzer62 63======================64 Running clang-objc-fuzzer65======================66 bin/clang-objc-fuzzer CORPUS_DIR67 68e.g. using the example objc corpus,69 70 bin/clang-objc-fuzzer <path to corpus_examples/objc> <path to new directory to store corpus findings>71 72 73=======================================================74 Building clang-proto-fuzzer (Linux-only instructions)75=======================================================76Install the necessary dependencies:77- binutils // needed for libprotobuf-mutator78- liblzma-dev // needed for libprotobuf-mutator79- libz-dev // needed for libprotobuf-mutator80- docbook2x // needed for libprotobuf-mutator81- Recent version of protobuf [3.3.0 is known to work]82 83Within your LLVM build directory, run CMake with the following variable84definitions:85- CMAKE_C_COMPILER=clang86- CMAKE_CXX_COMPILER=clang++87- LLVM_USE_SANITIZE_COVERAGE=YES88- LLVM_USE_SANITIZER=Address89- CLANG_ENABLE_PROTO_FUZZER=ON90 91Then build the clang-proto-fuzzer and clang-proto-to-cxx targets. Optionally,92you may also build clang-fuzzer with this setup.93 94Example:95 cd $LLVM_SOURCE_DIR96 mkdir build && cd build97 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \98 -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address \99 -DCLANG_ENABLE_PROTO_FUZZER=ON100 ninja clang-proto-fuzzer clang-proto-to-cxx101 102============================103 Running clang-proto-fuzzer104============================105 bin/clang-proto-fuzzer CORPUS_DIR106 107Arguments can be specified after -ignore_remaining_args=1 to modify the compiler108invocation. For example, the following command line will fuzz LLVM with a109custom optimization level and target triple:110 bin/clang-proto-fuzzer CORPUS_DIR -ignore_remaining_args=1 -O3 -triple \111 arm64apple-ios9112 113To translate a clang-proto-fuzzer corpus output to C++:114 bin/clang-proto-to-cxx CORPUS_OUTPUT_FILE115 116===================117 llvm-proto-fuzzer118===================119Like, clang-proto-fuzzer, llvm-proto-fuzzer is also a protobuf-mutator based120fuzzer. It receives as input a cxx_loop_proto which it then converts into a121string of valid LLVM IR: a function with either a single loop or two nested122loops. It then creates a new string of IR by running optimization passes over123the original IR. Currently, it only runs a loop-vectorize pass but more passes124can easily be added to the fuzzer. Once there are two versions of the input125function (optimized and not), llvm-proto-fuzzer uses LLVM's JIT Engine to126compile both functions. Lastly, it runs both functions on a suite of inputs and127checks that both functions behave the same on all inputs. In this way,128llvm-proto-fuzzer can find not only compiler crashes, but also miscompiles129originating from LLVM's optimization passes.130 131llvm-proto-fuzzer is built very similarly to clang-proto-fuzzer. You can run the132fuzzer with the following command:133 bin/clang-llvm-proto-fuzzer CORPUS_DIR134 135To translate a cxx_loop_proto file into LLVM IR do:136 bin/clang-loop-proto-to-llvm CORPUS_OUTPUT_FILE137To translate a cxx_loop_proto file into C++ do:138 bin/clang-loop-proto-to-cxx CORPUS_OUTPUT_FILE139 140Note: To get a higher number of executions per second with llvm-proto-fuzzer it141helps to build it without ASan instrumentation and with the -O2 flag. Because142the fuzzer is not only compiling code, but also running it, as the inputs get143large, the time necessary to fuzz one input can get very high.144Example:145 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \146 -DCLANG_ENABLE_PROTO_FUZZER=ON -DLLVM_USE_SANITIZE_COVERAGE=YES \147 -DCMAKE_CXX_FLAGS="-O2"148 ninja clang-llvm-proto-fuzzer clang-loop-proto-to-llvm149