56 lines
3.1 KiB
Markdown
56 lines
3.1 KiB
Markdown
# Test Flatbuffers library with help of libFuzzer
|
||
Test suite of Flatbuffers library has fuzzer section with tests are based on libFuzzer library.
|
||
|
||
> LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.
|
||
LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka “target function”);
|
||
the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage.
|
||
The code coverage information for libFuzzer is provided by LLVM’s SanitizerCoverage instrumentation.
|
||
|
||
For details about **libFuzzer** see: https://llvm.org/docs/LibFuzzer.html
|
||
|
||
To build and run these tests LLVM compiler (with clang frontend) and CMake should be installed before.
|
||
|
||
The fuzzer section include three tests:
|
||
- `verifier_fuzzer` checks stability of deserialization engine for `Monster` schema;
|
||
- `parser_fuzzer` checks stability of schema and json parser under various inputs;
|
||
- `scalar_parser` focused on validation of the parser while parse numeric scalars in schema and/or json files;
|
||
|
||
## Run tests with a specific locale
|
||
The grammar of the Flatbuffers library is based on printable-ASCII characters.
|
||
By design, the Flatbuffers library should be independent of the global or thread locales used by an end-user application.
|
||
Set environment variable `FLATBUFFERS_TEST_LOCALE` to run a fuzzer with a specific C-locale:
|
||
```sh
|
||
>FLATBUFFERS_TEST_LOCALE="" ./scalar_parser
|
||
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./parser_fuzzer
|
||
```
|
||
|
||
## Run fuzzer
|
||
These are examples of running a fuzzer.
|
||
Flags may vary and depend on a version of the libFuzzer library.
|
||
For details, run a fuzzer with `-help` flag: `./parser_fuzzer -help=1`
|
||
|
||
`./verifier_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_verifier/`
|
||
|
||
`./parser_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_parser/`
|
||
|
||
`./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 ../.corpus_parser/ ../.seed_parser/`
|
||
|
||
Flag `-only_ascii=1` is useful for fast number-compatibility checking while run `scalar_fuzzer`:
|
||
`./scalar_fuzzer -only_ascii=1 -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 -jobs=2 ../.corpus_parser/ ../.seed_parser/`
|
||
|
||
Run with a specific C-locale:
|
||
`FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 ../.corpus_parser/ ../.seed_parser/`
|
||
|
||
## Merge (minimize) corpus
|
||
The **libFuzzer** allow to filter (minimize) corpus with help of `-merge` flag:
|
||
> -merge
|
||
If set to 1, any corpus inputs from the 2nd, 3rd etc. corpus directories that trigger new code coverage will be merged into the first corpus directory.
|
||
Defaults to 0. This flag can be used to minimize a corpus.
|
||
|
||
Merge several seeds to one (a new collected corpus to the seed collection, for example):
|
||
`./scalar_fuzzer -merge=1 ../.seed_parser/ ../.corpus_parser/`
|
||
|
||
## Know limitations
|
||
- LLVM 7.0 std::regex library has problem with stack overflow, maximum length of input for `scalar_fuzzer` run should be limited to 3000.
|
||
Example: `./scalar_fuzzer -max_len=3000`
|