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