v8/test/fuzzer
eholk 3e1db847b3 [wasm] Syntax- and Type-aware Fuzzer
This is the beginning of a new fuzzer that generates
correct-by-construction Wasm modules. This should allow us to better
exercise the compiler and correctness aspects of fuzzing. It is based off
of ahaas' original Wasm fuzzer.

At the moment, it can generate expressions made up of most binops, and
also nested blocks with unconditional breaks. Future CLs will add
additional constructs, such as br_if, loops, memory access, etc.

The way the fuzzer works is that it starts with an array of arbitrary
data provided by libfuzzer. It uses the data to generate an expression.
Care is taken to make use of the entire string. Basically, the
generator has a bunch of grammar-like rules for how to construct an
expression of a given type. For example, an i32 can be made by adding
two other i32s, or by wrapping an i64. The process then continues
recursively until all the data is consumed.

We generate an expression from a slice of data as follows:
* If the slice is less than or equal to the size of the type (e.g. 4
  bytes for i32), then it will emit the entire slice as a constant.
* Otherwise, it will consume the first 4 bytes of the slice and use
  this to select which rule to apply. Each rule then consumes the
  remainder of the slice in an appropriate way. For example:
  * Unary ops use the remainder of the slice to generate the argument.
  * Binary ops consume another four bytes and mod this with the length
    of the remaining slice to split the slice into two parts. Each of
    these subslices are then used to generate one of the arguments to
    the binop.
  * Blocks are basically like a unary op, but a stack of block types is
    maintained to facilitate branches. For blocks that end in a break,
    the first four bytes of a slice are used to select the break depth
    and the stack determines what type of expression to generate.
The goal is that once this generator is complete, it will provide a one
to one mapping between binary strings and valid Wasm modules.

Review-Url: https://codereview.chromium.org/2658723006
Cr-Commit-Position: refs/heads/master@{#43289}
2017-02-17 17:06:29 +00:00
..
json Add json fuzzer 2016-02-02 11:29:01 +00:00
parser Add a library suitable for libfuzzer with a small unit test runner shell 2016-01-26 10:39:03 +00:00
regexp [regexp] add fuzzer support for regexp parser and compiler. 2016-02-01 14:00:38 +00:00
wasm_call [wasm] Add a new fuzzer which can also test wasm function calls. 2016-10-24 11:15:00 +00:00
wasm_code [wasm] Create a new fuzzer for wasm code. 2016-08-29 13:56:00 +00:00
wasm_compile [wasm] Syntax- and Type-aware Fuzzer 2017-02-17 17:06:29 +00:00
wasm_data_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_function_sigs_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_globals_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_imports_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_memory_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_names_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm_types_section [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
DEPS Add a library suitable for libfuzzer with a small unit test runner shell 2016-01-26 10:39:03 +00:00
fuzzer-support.cc Provide a convenience array buffer allocator 2016-06-29 07:42:40 +00:00
fuzzer-support.h Provide a convenience array buffer allocator 2016-06-29 07:42:40 +00:00
fuzzer.cc [wasm] Fix -Wsign-compare warnings. 2016-11-10 12:51:05 +00:00
fuzzer.gyp [wasm] Syntax- and Type-aware Fuzzer 2017-02-17 17:06:29 +00:00
fuzzer.isolate [wasm] Syntax- and Type-aware Fuzzer 2017-02-17 17:06:29 +00:00
fuzzer.status Add a library suitable for libfuzzer with a small unit test runner shell 2016-01-26 10:39:03 +00:00
json.cc Add GC request to libFuzzers in attempt to avoid parasitic coverage. 2016-04-28 13:32:28 +00:00
parser.cc Reland of land: [Parse] ParseInfo owns the parsing Zone. (patchset #1 id:1 of https://codereview.chromium.org/2683733002/ ) 2017-02-07 20:46:47 +00:00
README.md [fuzzer] Format README.md 2017-02-13 08:42:26 +00:00
regexp.cc [regexp fuzzer] Let the fuzzer input select the regexp flag. 2016-11-22 12:59:38 +00:00
testcfg.py [wasm] Syntax- and Type-aware Fuzzer 2017-02-17 17:06:29 +00:00
wasm_asmjs.tar.gz.sha1 [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00
wasm-asmjs.cc [wasm] Change the constant kV8MaxWasmTableSize to a command line flag. 2017-01-24 10:12:22 +00:00
wasm-call.cc [wasm][fuzzer] Small fixes in the correctness fuzzer result comparison. 2017-02-16 11:23:29 +00:00
wasm-code.cc [wasm][fuzzer] Small fixes in the correctness fuzzer result comparison. 2017-02-16 11:23:29 +00:00
wasm-compile.cc [wasm] Syntax- and Type-aware Fuzzer 2017-02-17 17:06:29 +00:00
wasm-data-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-function-sigs-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-globals-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-imports-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-memory-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-names-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-section-fuzzers.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm-section-fuzzers.h [wasm] Master CL for Binary 0xC changes. 2016-09-27 20:46:30 +00:00
wasm-types-section.cc [iwyu, wasm] Remove unallowed includes to objects-inl.h from wasm. 2017-02-13 15:05:37 +00:00
wasm.cc [wasm] Change the constant kV8MaxWasmTableSize to a command line flag. 2017-01-24 10:12:22 +00:00
wasm.tar.gz.sha1 [wasm] Write fuzzers for single wasm sections. 2016-09-14 11:17:53 +00:00

How to make a libFuzzer fuzzer in V8

This document describes how to make a new libFuzzer fuzzer for V8. A general introduction to libFuzzer can be found here. In short, libFuzzer is an in-process coverage-driven evolutionary fuzzer. libFuzzer serves you with a sequence of byte arrays that you can use to test your code. libFuzzer tries to generate this sequence of byte arrays in a way that maximizes test coverage.

Warning: By itself libFuzzer typically does not generate valid JavaScript code.

Changes to V8

tldr: Do the same as https://codereview.chromium.org/2280623002 to introduce a new fuzzer to V8.

This is a step by step guide on how to make a new fuzzer in V8. In the example the fuzzer is called foo.

  1. Copy one of the existing fuzzer implementations in test/fuzzer/, e.g. cp wasm.cc foo.cc

    • Copying an existing fuzzer is a good idea to get all the required setup, e.g. setting up the isolate
  2. Create a directory called foo in test/fuzzer/ which contains at least one file

    • The file is used by the trybots to check whether the fuzzer actually compiles and runs
  3. Copy the build rules of an existing fuzzer in BUILD.gn, e.g. the build rules for the wasm.cc fuzzer are v8_source_set("wasm_fuzzer") and v8_fuzzer("wasm_fuzzer"). Note that the name has to be the name of the directory created in Step 2 + _fuzzer so that the scripts on the trybots work

  4. Now you can already compile the fuzzer, e.g. with ninja -j 1000 -C out/x64.debug/v8_simple_foo_fuzzer

    • Use this binary to reproduce issues found by cluster fuzz, e.g. out/x64.debug/v8_simple_foo_fuzzer testcase.foo
  5. Copy the build rules of an existing fuzzer in test/fuzzer/fuzzer.gyp, e.g. the build rules for the wasm.cc fuzzer are v8_simple_wasm_fuzzer and wasm_fuzzer_lib

    • This build rule is needed to compile with gyp
  6. Copy the binary name and the test directory name in test/fuzzer/fuzzer.isolate

  7. Add the fuzzer to the FuzzerTestSuite in test/fuzzer/testcfg.py

    • This step is needed to run the fuzzer with the files created in Step 2 on the trybots
  8. Commit the changes described above to the V8 repository

Changes to Chromium

tldr: Do the same as https://codereview.chromium.org/2344823002 to add the new fuzzer to cluster fuzz.

  1. Copy the build rules of an existing fuzzer in testing/libfuzzer/fuzzers/BUILD.gn, e.g. the build rule for the wasm.cc fuzzer is v8_wasm_fuzzer. There is no need to set a dictionary , or a seed_corpus. See chromium-fuzzing-getting-started for more information.

  2. Compile the fuzzer in chromium (for different configurations see: https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md):

    • gn gen out/libfuzzer '--args=use_libfuzzer=true is_asan=true is_debug=false enable_nacl=false'

    • ninja -j 1000 -C out/libfuzzer/ v8_foo_fuzzer

  3. Run the fuzzer locally

    • mkdir /tmp/empty_corpus && out/libfuzzer/v8_foo_fuzzer /tmp/empty_corpus