150
|
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
|