Changeset View
Changeset View
Standalone View
Standalone View
doc/fuzzing.md
Fuzz-testing Bitcoin Core | Fuzz-testing Bitcoin Core | ||||
deadalnix: Out of the scope for this patch, but it looks like something that should be updated. | |||||
FabienAuthorUnsubmitted Done Inline ActionsYes, all the fuzzy-related files need update. I'm gonna do them all in one after I'm done with all the backports (there are not plenty) in order to avoid conflicts. Fabien: Yes, all the fuzzy-related files need update. I'm gonna do them all in one after I'm done with… | |||||
========================== | ========================== | ||||
A special test harness `test_bitcoin_fuzzy` is provided to provide an easy | A special test harness `test_bitcoin_fuzzy` is provided to provide an easy | ||||
entry point for fuzzers and the like. In this document we'll describe how to | entry point for fuzzers and the like. In this document we'll describe how to | ||||
use it with AFL. | use it with AFL and libFuzzer. | ||||
Building AFL | ## AFL | ||||
------------- | |||||
### Building AFL | |||||
It is recommended to always use the latest version of afl: | It is recommended to always use the latest version of afl: | ||||
``` | ``` | ||||
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz | wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz | ||||
tar -zxvf afl-latest.tgz | tar -zxvf afl-latest.tgz | ||||
cd afl-<version> | cd afl-<version> | ||||
make | make | ||||
export AFLPATH=$PWD | export AFLPATH=$PWD | ||||
``` | ``` | ||||
Instrumentation | ### Instrumentation | ||||
---------------- | |||||
To build Bitcoin Core using AFL instrumentation (this assumes that the | To build Bitcoin Core using AFL instrumentation (this assumes that the | ||||
`AFLPATH` was set as above): | `AFLPATH` was set as above): | ||||
``` | ``` | ||||
./configure --disable-ccache --disable-shared --enable-tests CC=${AFLPATH}/afl-gcc CXX=${AFLPATH}/afl-g++ | ./configure --disable-ccache --disable-shared --enable-tests CC=${AFLPATH}/afl-gcc CXX=${AFLPATH}/afl-g++ | ||||
export AFL_HARDEN=1 | export AFL_HARDEN=1 | ||||
cd src/ | cd src/ | ||||
make test/test_bitcoin_fuzzy | make test/test_bitcoin_fuzzy | ||||
``` | ``` | ||||
We disable ccache because we don't want to pollute the ccache with instrumented | We disable ccache because we don't want to pollute the ccache with instrumented | ||||
objects, and similarly don't want to use non-instrumented cached objects linked | objects, and similarly don't want to use non-instrumented cached objects linked | ||||
in. | in. | ||||
The fuzzing can be sped up significantly (~200x) by using `afl-clang-fast` and | The fuzzing can be sped up significantly (~200x) by using `afl-clang-fast` and | ||||
`afl-clang-fast++` in place of `afl-gcc` and `afl-g++` when compiling. When | `afl-clang-fast++` in place of `afl-gcc` and `afl-g++` when compiling. When | ||||
compiling using `afl-clang-fast`/`afl-clang-fast++` the resulting | compiling using `afl-clang-fast`/`afl-clang-fast++` the resulting | ||||
`test_bitcoin_fuzzy` binary will be instrumented in such a way that the AFL | `test_bitcoin_fuzzy` binary will be instrumented in such a way that the AFL | ||||
features "persistent mode" and "deferred forkserver" can be used. See | features "persistent mode" and "deferred forkserver" can be used. See | ||||
https://github.com/mcarpenter/afl/tree/master/llvm_mode for details. | https://github.com/mcarpenter/afl/tree/master/llvm_mode for details. | ||||
Preparing fuzzing | ### Preparing fuzzing | ||||
------------------ | |||||
AFL needs an input directory with examples, and an output directory where it | AFL needs an input directory with examples, and an output directory where it | ||||
will place examples that it found. These can be anywhere in the file system, | will place examples that it found. These can be anywhere in the file system, | ||||
we'll define environment variables to make it easy to reference them. | we'll define environment variables to make it easy to reference them. | ||||
``` | ``` | ||||
mkdir inputs | mkdir inputs | ||||
AFLIN=$PWD/inputs | AFLIN=$PWD/inputs | ||||
mkdir outputs | mkdir outputs | ||||
AFLOUT=$PWD/outputs | AFLOUT=$PWD/outputs | ||||
``` | ``` | ||||
Example inputs are available from: | Example inputs are available from: | ||||
- https://download.visucore.com/bitcoin/bitcoin_fuzzy_in.tar.xz | - https://download.visucore.com/bitcoin/bitcoin_fuzzy_in.tar.xz | ||||
- http://strateman.ninja/fuzzing.tar.xz | - http://strateman.ninja/fuzzing.tar.xz | ||||
Extract these (or other starting inputs) into the `inputs` directory before starting fuzzing. | Extract these (or other starting inputs) into the `inputs` directory before starting fuzzing. | ||||
Fuzzing | ### Fuzzing | ||||
-------- | |||||
To start the actual fuzzing use: | To start the actual fuzzing use: | ||||
``` | ``` | ||||
$AFLPATH/afl-fuzz -i ${AFLIN} -o ${AFLOUT} -m52 -- test/test_bitcoin_fuzzy | $AFLPATH/afl-fuzz -i ${AFLIN} -o ${AFLOUT} -m52 -- test/test_bitcoin_fuzzy | ||||
``` | ``` | ||||
You may have to change a few kernel parameters to test optimally - `afl-fuzz` | You may have to change a few kernel parameters to test optimally - `afl-fuzz` | ||||
will print an error and suggestion if so. | will print an error and suggestion if so. | ||||
## libFuzzer | |||||
A recent version of `clang`, the address sanitizer and libFuzzer is needed (all | |||||
found in the `compiler-rt` runtime libraries package). | |||||
To build the `test/test_bitcoin_fuzzy` executable run | |||||
``` | |||||
./configure --disable-ccache --with-sanitizers=fuzzer,address CC=clang CXX=clang++ | |||||
make | |||||
``` | |||||
The fuzzer needs some inputs to work on, but the inputs or seeds can be used | |||||
interchangably between libFuzzer and AFL. | |||||
See https://llvm.org/docs/LibFuzzer.html#running on how to run the libFuzzer | |||||
instrumented executable. |
Out of the scope for this patch, but it looks like something that should be updated.