1This directory contains three utilities for fuzzing Clang: clang-fuzzer, 2clang-objc-fuzzer, and clang-proto-fuzzer. All use libFuzzer to generate inputs 3to 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 therefore 7primarily 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 to 10generate 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 that 14class, 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-fuzzer 21=================================== 22Within your LLVM build directory, run CMake with the following variable 23definitions: 24- CMAKE_C_COMPILER=clang 25- CMAKE_CXX_COMPILER=clang++ 26- LLVM_USE_SANITIZE_COVERAGE=YES 27- LLVM_USE_SANITIZER=Address 28 29Then build the clang-fuzzer target. 30 31Example: 32 cd $LLVM_SOURCE_DIR 33 mkdir build && cd build 34 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ 35 -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address 36 ninja clang-fuzzer 37 38====================== 39 Running clang-fuzzer 40====================== 41 bin/clang-fuzzer CORPUS_DIR 42 43 44=================================== 45 Building clang-objc-fuzzer 46=================================== 47Within your LLVM build directory, run CMake with the following variable 48definitions: 49- CMAKE_C_COMPILER=clang 50- CMAKE_CXX_COMPILER=clang++ 51- LLVM_USE_SANITIZE_COVERAGE=YES 52- LLVM_USE_SANITIZER=Address 53 54Then build the clang-objc-fuzzer target. 55 56Example: 57 cd $LLVM_SOURCE_DIR 58 mkdir build && cd build 59 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ 60 -DLLVM_USE_SANITIZE_COVERAGE=YES -DLLVM_USE_SANITIZER=Address 61 ninja clang-objc-fuzzer 62 63====================== 64 Running clang-objc-fuzzer 65====================== 66 bin/clang-objc-fuzzer CORPUS_DIR 67 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-mutator 78- liblzma-dev // needed for libprotobuf-mutator 79- libz-dev // needed for libprotobuf-mutator 80- docbook2x // needed for libprotobuf-mutator 81- Recent version of protobuf [3.3.0 is known to work] 82 83Within your LLVM build directory, run CMake with the following variable 84definitions: 85- CMAKE_C_COMPILER=clang 86- CMAKE_CXX_COMPILER=clang++ 87- LLVM_USE_SANITIZE_COVERAGE=YES 88- LLVM_USE_SANITIZER=Address 89- CLANG_ENABLE_PROTO_FUZZER=ON 90 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_DIR 96 mkdir build && cd build 97 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=ON 100 ninja clang-proto-fuzzer clang-proto-to-cxx 101 102This directory also contains a Dockerfile which sets up all required 103dependencies and builds the fuzzers. 104 105============================ 106 Running clang-proto-fuzzer 107============================ 108 bin/clang-proto-fuzzer CORPUS_DIR 109 110Arguments can be specified after -ignore_remaining_args=1 to modify the compiler 111invocation. For example, the following command line will fuzz LLVM with a 112custom optimization level and target triple: 113 bin/clang-proto-fuzzer CORPUS_DIR -ignore_remaining_args=1 -O3 -triple \ 114 arm64apple-ios9 115 116To translate a clang-proto-fuzzer corpus output to C++: 117 bin/clang-proto-to-cxx CORPUS_OUTPUT_FILE 118 119=================== 120 llvm-proto-fuzzer 121=================== 122Like, clang-proto-fuzzer, llvm-proto-fuzzer is also a protobuf-mutator based 123fuzzer. It receives as input a cxx_loop_proto which it then converts into a 124string of valid LLVM IR: a function with either a single loop or two nested 125loops. It then creates a new string of IR by running optimization passes over 126the original IR. Currently, it only runs a loop-vectorize pass but more passes 127can easily be added to the fuzzer. Once there are two versions of the input 128function (optimized and not), llvm-proto-fuzzer uses LLVM's JIT Engine to 129compile both functions. Lastly, it runs both functions on a suite of inputs and 130checks that both functions behave the same on all inputs. In this way, 131llvm-proto-fuzzer can find not only compiler crashes, but also miscompiles 132originating from LLVM's optimization passes. 133 134llvm-proto-fuzzer is built very similarly to clang-proto-fuzzer. You can run the 135fuzzer with the following command: 136 bin/clang-llvm-proto-fuzzer CORPUS_DIR 137 138To translate a cxx_loop_proto file into LLVM IR do: 139 bin/clang-loop-proto-to-llvm CORPUS_OUTPUT_FILE 140To translate a cxx_loop_proto file into C++ do: 141 bin/clang-loop-proto-to-cxx CORPUS_OUTPUT_FILE 142 143Note: To get a higher number of executions per second with llvm-proto-fuzzer it 144helps to build it without ASan instrumentation and with the -O2 flag. Because 145the fuzzer is not only compiling code, but also running it, as the inputs get 146large, the time necessary to fuzz one input can get very high. 147Example: 148 cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ 149 -DCLANG_ENABLE_PROTO_FUZZER=ON -DLLVM_USE_SANITIZE_COVERAGE=YES \ 150 -DCMAKE_CXX_FLAGS="-O2" 151 ninja clang-llvm-proto-fuzzer clang-loop-proto-to-llvm 152