Home | History | Annotate | Line # | Download | only in clang-fuzzer
      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