APPS: Remove make_config_name, use CONF_get1_default_config_file instead
[oweals/openssl.git] / fuzz / README.md
index 8536566ec1c3d75ace1ee538dc986b0f2c1bd96f..c8dbf454b0064a4afeef7b7a6ad995dd9842f4e3 100644 (file)
-# I Can Haz Fuzz?
+Fuzzing OpenSSL
+===============
+
+OpenSSL can use either LibFuzzer or AFL to do fuzzing.
 
 LibFuzzer
-=========
+---------
+
+How to fuzz OpenSSL with [libfuzzer](http://llvm.org/docs/LibFuzzer.html),
+starting from a vanilla+OpenSSH server Ubuntu install.
+
+With `clang` from a package manager
+-----------------------------------
 
-Or, how to fuzz OpenSSL with [libfuzzer](http://llvm.org/docs/LibFuzzer.html).
+Install `clang`, which [ships with `libfuzzer`](http://llvm.org/docs/LibFuzzer.html#fuzzer-usage)
+since version 6.0:
 
-Starting from a vanilla+OpenSSH server Ubuntu install.
+    sudo apt-get install clang
 
-Use Chrome's handy recent build of clang. Older versions may also work.
+Configure `openssl` for fuzzing. For now, you'll still need to pass in the path
+to the `libFuzzer` library file while configuring; this is represented as
+`$PATH_TO_LIBFUZZER` below. A typical value would be
+`/usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.fuzzer-x86_64.a`.
+
+    CC=clang ./config enable-fuzz-libfuzzer \
+            --with-fuzzer-lib=$PATH_TO_LIBFUZZER \
+            -DPEDANTIC enable-asan enable-ubsan no-shared \
+            -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \
+            -fsanitize=fuzzer-no-link \
+            enable-ec_nistp_64_gcc_128 -fno-sanitize=alignment \
+            enable-weak-ssl-ciphers enable-rc5 enable-md2 \
+            enable-ssl3 enable-ssl3-method enable-nextprotoneg \
+            --debug
 
-    $ sudo apt-get install git
-    $ mkdir git-work
-    $ git clone https://chromium.googlesource.com/chromium/src/tools/clang
-    $ clang/scripts/update.py
+Compile:
 
-You may want to git pull and re-run the update from time to time.
+    sudo apt-get install make
+    make clean
+    LDCMD=clang++ make -j4
 
-Update your path:
+Finally, perform the actual fuzzing:
 
-    $ PATH=~/third_party/llvm-build/Release+Asserts/bin/:$PATH
+    fuzz/helper.py $FUZZER
 
-Get and build libFuzzer (there is a git mirror at
-https://github.com/llvm-mirror/llvm/tree/master/lib/Fuzzer if you prefer):
+where $FUZZER is one of the executables in `fuzz/`.
+It will run until you stop it.
 
-    $ cd
-    $ sudo apt-get install subversion
-    $ mkdir svn-work
-    $ cd svn-work
-    $ svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer Fuzzer
-    $ cd Fuzzer
-    $ clang++ -c -g -O2 -std=c++11 *.cpp
-    $ ar r libFuzzer.a *.o
-    $ ranlib libFuzzer.a
+If you get a crash, you should find a corresponding input file in
+`fuzz/corpora/$FUZZER-crash/`.
 
-Configure for fuzzing:
+With `clang` from source/pre-built binaries
+-------------------------------------------
 
-    $ CC=clang ./config enable-fuzz-libfuzzer \
-            --with-fuzzer-include=../../svn-work/Fuzzer \
-            --with-fuzzer-lib=../../svn-work/Fuzzer/libFuzzer \
+You may also wish to use a pre-built binary from the [LLVM Download
+site](http://releases.llvm.org/download.html), or to [build `clang` from
+source](https://clang.llvm.org/get_started.html). After adding `clang` to your
+path and locating the `libfuzzer` library file, the procedure for configuring
+fuzzing is the same, except that you also need to specify
+a `--with-fuzzer-include` option, which should be the parent directory of the
+prebuilt fuzzer library. This is represented as `$PATH_TO_LIBFUZZER_DIR` below.
+
+    CC=clang ./config enable-fuzz-libfuzzer \
+            --with-fuzzer-include=$PATH_TO_LIBFUZZER_DIR \
+            --with-fuzzer-lib=$PATH_TO_LIBFUZZER \
             -DPEDANTIC enable-asan enable-ubsan no-shared \
             -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \
-            -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp \
-            enable-ec_nistp_64_gcc_128 -fno-sanitize=alignment enable-tls1_3 \
+            -fsanitize=fuzzer-no-link \
+            enable-ec_nistp_64_gcc_128 -fno-sanitize=alignment \
             enable-weak-ssl-ciphers enable-rc5 enable-md2 \
             enable-ssl3 enable-ssl3-method enable-nextprotoneg \
             --debug
-    $ sudo apt-get install make
-    $ LDCMD=clang++ make -j
-    $ fuzz/helper.py $FUZZER
-
-Where $FUZZER is one of the executables in `fuzz/`.
-
-If you get a crash, you should find a corresponding input file in
-`fuzz/corpora/$FUZZER-crash/`.
 
 AFL
-===
+---
+
+This is an alternative to using LibFuzzer.
 
 Configure for fuzzing:
 
-    sudo apt-get install afl-clang
-    $ CC=afl-clang-fast ./config enable-fuzz-afl no-shared -DPEDANTIC \
-        enable-tls1_3 enable-weak-ssl-ciphers enable-rc5 enable-md2 \
-        enable-ssl3 enable-ssl3-method enable-nextprotoneg \
+    sudo apt-get install afl-clang
+    CC=afl-clang-fast ./config enable-fuzz-afl no-shared no-module \
+        -DPEDANTIC enable-tls1_3 enable-weak-ssl-ciphers enable-rc5 \
+        enable-md2 enable-ssl3 enable-ssl3-method enable-nextprotoneg \
         enable-ec_nistp_64_gcc_128 -fno-sanitize=alignment \
         --debug
-    $ make
+    make clean
+    make
 
 The following options can also be enabled: enable-asan, enable-ubsan, enable-msan
 
 Run one of the fuzzers:
 
-    afl-fuzz -i fuzz/corpora/$FUZZER -o fuzz/corpora/$FUZZER/out fuzz/$FUZZER
+    afl-fuzz -i fuzz/corpora/$FUZZER -o fuzz/corpora/$FUZZER/out fuzz/$FUZZER
 
 Where $FUZZER is one of the executables in `fuzz/`.
 
 Reproducing issues
-==================
+------------------
 
 If a fuzzer generates a reproducible error, you can reproduce the problem using
 the fuzz/*-test binaries and the file generated by the fuzzer. They binaries
@@ -89,10 +108,10 @@ reproduce the generated random numbers.
 
 To reproduce the crash you can run:
 
-    fuzz/$FUZZER-test $file
+    fuzz/$FUZZER-test $file
 
 Random numbers
-==============
+--------------
 
 The client and server fuzzer normally generate random numbers as part of the TLS
 connection setup. This results in the coverage of the fuzzing corpus changing
@@ -111,16 +130,17 @@ the same client hello with the same random number in it, and so the server, as
 emulated by the file, can be generated for that client hello.
 
 Coverage changes
-================
+----------------
 
 Since the corpus depends on the default behaviour of the client and the server,
 changes in what they send by default will have an impact on the coverage. The
 corpus will need to be updated in that case.
 
 Updating the corpus
-===================
+-------------------
 
 The client and server corpus is generated with multiple config options:
+
 - The options as documented above
 - Without enable-ec_nistp_64_gcc_128 and without --debug
 - With no-asm
@@ -129,3 +149,13 @@ The client and server corpus is generated with multiple config options:
 
 The libfuzzer merge option is used to add the additional coverage
 from each config to the minimal set.
+
+Minimizing the corpus
+---------------------
+
+When you have gathered corpus data from more than one fuzzer run
+or for any other reason want to to minimize the data
+in some corpus subdirectory `fuzz/corpora/DIR` this can be done as follows:
+
+    mkdir fuzz/corpora/NEWDIR
+    fuzz/$FUZZER -merge=1 fuzz/corpora/NEWDIR fuzz/corpora/DIR