1 This directory contains three utilities for fuzzing Clang: clang-fuzzer, 2 clang-objc-fuzzer, and clang-proto-fuzzer. All use libFuzzer to generate inputs 3 to clang via coverage-guided mutation. 4 5 The three utilities differ, however, in how they structure inputs to Clang. 6 clang-fuzzer makes no attempt to generate valid C++ programs and is therefore 7 primarily useful for stressing the surface layers of Clang (i.e. lexer, parser). 8 9 clang-objc-fuzzer is similar but for Objective-C: it makes no attempt to 10 generate a valid Objective-C program. 11 12 clang-proto-fuzzer uses a protobuf class to describe a subset of the C++ 13 language and then uses libprotobuf-mutator to mutate instantiations of that 14 class, producing valid C++ programs in the process. As a result, 15 clang-proto-fuzzer is better at stressing deeper layers of Clang and LLVM. 16 17 Some of the fuzzers have example corpuses inside the corpus_examples directory. 18 19 =================================== 20 Building clang-fuzzer 21 =================================== 22 Within your LLVM build directory, run CMake with the following variable 23 definitions: 24 - CMAKE_C_COMPILER=clang 25 - CMAKE_CXX_COMPILER=clang++ 26 - LLVM_USE_SANITIZE_COVERAGE=YES 27 - LLVM_USE_SANITIZER=Address 28 29 Then build the clang-fuzzer target. 30 31 Example: 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 =================================== 47 Within your LLVM build directory, run CMake with the following variable 48 definitions: 49 - CMAKE_C_COMPILER=clang 50 - CMAKE_CXX_COMPILER=clang++ 51 - LLVM_USE_SANITIZE_COVERAGE=YES 52 - LLVM_USE_SANITIZER=Address 53 54 Then build the clang-objc-fuzzer target. 55 56 Example: 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 68 e.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 ======================================================= 76 Install 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 83 Within your LLVM build directory, run CMake with the following variable 84 definitions: 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 91 Then build the clang-proto-fuzzer and clang-proto-to-cxx targets. Optionally, 92 you may also build clang-fuzzer with this setup. 93 94 Example: 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 102 This directory also contains a Dockerfile which sets up all required 103 dependencies and builds the fuzzers. 104 105 ============================ 106 Running clang-proto-fuzzer 107 ============================ 108 bin/clang-proto-fuzzer CORPUS_DIR 109 110 Arguments can be specified after -ignore_remaining_args=1 to modify the compiler 111 invocation. For example, the following command line will fuzz LLVM with a 112 custom optimization level and target triple: 113 bin/clang-proto-fuzzer CORPUS_DIR -ignore_remaining_args=1 -O3 -triple \ 114 arm64apple-ios9 115 116 To 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 =================== 122 Like, clang-proto-fuzzer, llvm-proto-fuzzer is also a protobuf-mutator based 123 fuzzer. It receives as input a cxx_loop_proto which it then converts into a 124 string of valid LLVM IR: a function with either a single loop or two nested 125 loops. It then creates a new string of IR by running optimization passes over 126 the original IR. Currently, it only runs a loop-vectorize pass but more passes 127 can easily be added to the fuzzer. Once there are two versions of the input 128 function (optimized and not), llvm-proto-fuzzer uses LLVM's JIT Engine to 129 compile both functions. Lastly, it runs both functions on a suite of inputs and 130 checks that both functions behave the same on all inputs. In this way, 131 llvm-proto-fuzzer can find not only compiler crashes, but also miscompiles 132 originating from LLVM's optimization passes. 133 134 llvm-proto-fuzzer is built very similarly to clang-proto-fuzzer. You can run the 135 fuzzer with the following command: 136 bin/clang-llvm-proto-fuzzer CORPUS_DIR 137 138 To translate a cxx_loop_proto file into LLVM IR do: 139 bin/clang-loop-proto-to-llvm CORPUS_OUTPUT_FILE 140 To translate a cxx_loop_proto file into C++ do: 141 bin/clang-loop-proto-to-cxx CORPUS_OUTPUT_FILE 142 143 Note: To get a higher number of executions per second with llvm-proto-fuzzer it 144 helps to build it without ASan instrumentation and with the -O2 flag. Because 145 the fuzzer is not only compiling code, but also running it, as the inputs get 146 large, the time necessary to fuzz one input can get very high. 147 Example: 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