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