xref: /PHP-8.0/sapi/fuzzer/README.md (revision a88226d1)
1Fuzzing SAPI for PHP
2--------------------
3
4The following `./configure` options can be used to enable the fuzzing SAPI, as well as all availablefuzzers. If you don't build the exif/json/mbstring extensions, fuzzers for these extensions will not be built.
5
6```sh
7CC=clang CXX=clang++ \
8./configure \
9    --disable-all \
10    --enable-fuzzer \
11    --with-pic \
12    --enable-debug-assertions \
13    --enable-exif \
14    --enable-mbstring
15```
16
17The `--with-pic` option is required to avoid a linking failure. The `--enable-debug-assertions` option can be used to enable debug assertions despite the use of a release build.
18
19You will need a recent version of clang that supports the `-fsanitize=fuzzer-no-link` option.
20
21When running `make` it creates these binaries in `sapi/fuzzer/`:
22
23* `php-fuzz-parser`: Fuzzing language parser and compiler
24* `php-fuzz-unserialize`: Fuzzing unserialize() function
25* `php-fuzz-unserializehash`: Fuzzing unserialize() for HashContext objects
26* `php-fuzz-json`: Fuzzing JSON parser (requires --enable-json)
27* `php-fuzz-exif`: Fuzzing `exif_read_data()` function (requires --enable-exif)
28* `php-fuzz-mbstring`: Fuzzing `mb_ereg[i]()` (requires --enable-mbstring)
29* `php-fuzz-execute`: Fuzzing the executor
30
31Some fuzzers have a seed corpus in `sapi/fuzzer/corpus`. You can use it as follows:
32
33```sh
34cp -r sapi/fuzzer/corpus/exif ./my-exif-corpus
35sapi/fuzzer/php-fuzz-exif ./my-exif-corpus
36```
37
38For the unserialize fuzzer, a dictionary of internal classes should be generated first:
39
40```sh
41sapi/cli/php sapi/fuzzer/generate_unserialize_dict.php
42cp -r sapi/fuzzer/corpus/unserialize ./my-unserialize-corpus
43sapi/fuzzer/php-fuzz-unserialize -dict=$PWD/sapi/fuzzer/dict/unserialize ./my-unserialize-corpus
44```
45
46For the unserializehash fuzzer, generate a corpus of initial hash serializations:
47
48```sh
49sapi/cli/php sapi/fuzzer/generate_unserializehash_corpus.php
50cp -r sapi/fuzzer/corpus/unserializehash ./my-unserialize-corpus
51sapi/fuzzer/php-fuzz-unserializehash ./my-unserialize-corpus
52```
53
54For the parser fuzzer, a corpus may be generated from Zend test files:
55
56```sh
57sapi/cli/php sapi/fuzzer/generate_parser_corpus.php
58mkdir ./my-parser-corpus
59sapi/fuzzer/php-fuzz-parser -merge=1 ./my-parser-corpus sapi/fuzzer/corpus/parser
60sapi/fuzzer/php-fuzz-parser -only_ascii=1 ./my-parser-corpus
61```
62
63For the mbstring fuzzer, you may want to build the libonig dependency with instrumentation. At this time, libonig is not clean under ubsan, so only the fuzzer and address sanitizers may be used.
64
65```sh
66git clone https://github.com/kkos/oniguruma.git
67pushd oniguruma
68autoreconf -vfi
69./configure CC=clang CFLAGS="-fsanitize=fuzzer-no-link,address -O2 -g"
70make
71popd
72
73export ONIG_CFLAGS="-I$PWD/oniguruma/src"
74export ONIG_LIBS="-L$PWD/oniguruma/src/.libs -l:libonig.a"
75```
76
77This will link an instrumented libonig statically into the PHP binary.
78