Home | History | Annotate | Download | only in fuzzer
      1 # Test Flatbuffers library with help of libFuzzer
      2 Test suite of Flatbuffers library has fuzzer section with tests are based on libFuzzer library.
      3 
      4 > LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.
      5 LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka target function);
      6 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.
      7 The code coverage information for libFuzzer is provided by LLVMs SanitizerCoverage instrumentation.
      8 
      9 For details about **libFuzzer** see: https://llvm.org/docs/LibFuzzer.html
     10 
     11 To build and run these tests LLVM compiler (with clang frontend) and CMake should be installed before.
     12 
     13 The fuzzer section include three tests:
     14 - `verifier_fuzzer` checks stability of deserialization engine for `Monster` schema;
     15 - `parser_fuzzer` checks stability of schema and json parser under various inputs;
     16 - `scalar_parser` focused on validation of the parser while parse numeric scalars in schema and/or json files;
     17 
     18 ## Run tests with a specific locale
     19 The grammar of the Flatbuffers library is based on printable-ASCII characters.
     20 By design, the Flatbuffers library should be independent of the global or thread locales used by an end-user application.
     21 Set environment variable `FLATBUFFERS_TEST_LOCALE` to run a fuzzer with a specific C-locale:
     22 ```sh
     23 >FLATBUFFERS_TEST_LOCALE="" ./scalar_parser
     24 >FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./parser_fuzzer
     25 ```
     26 
     27 ## Run fuzzer
     28 These are examples of running a fuzzer.
     29 Flags may vary and depend on a version of the libFuzzer library.
     30 For details, run a fuzzer with `-help` flag: `./parser_fuzzer -help=1`
     31 
     32 `./verifier_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_verifier/`
     33 
     34 `./parser_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_parser/`
     35 
     36 `./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 ../.corpus_parser/ ../.seed_parser/`
     37 
     38 Flag `-only_ascii=1` is useful for fast number-compatibility checking while run `scalar_fuzzer`:  
     39 `./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/`
     40 
     41 Run with a specific C-locale:  
     42 `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/`
     43 
     44 ## Merge (minimize) corpus
     45 The **libFuzzer** allow to filter (minimize) corpus with help of `-merge` flag:
     46 > -merge
     47     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.
     48     Defaults to 0. This flag can be used to minimize a corpus.
     49 
     50 Merge several seeds to one (a new collected corpus to the seed collection, for example):
     51 `./scalar_fuzzer -merge=1 ../.seed_parser/ ../.corpus_parser/`
     52 
     53 ## Know limitations
     54 - LLVM 7.0 std::regex library has problem with stack overflow, maximum length of input for `scalar_fuzzer` run should be limited to 3000.
     55   Example: `./scalar_fuzzer -max_len=3000`
     56