# Write a fuzzer

Fuchsia's toolchain supports fuzzing using LLVM's [libFuzzer]. To create a fuzzer for a particular
interface, you need to implement a [fuzz target function][fuzz-target] that uses a provided sequence
of bytes to exercise the interface. The sequence of bytes is referred to as a fuzzer "input". The
fuzz target function is used by libFuzzer to search for inputs that cause panics or other errors.

## Sample Code to Fuzz {#samples}

For each of the examples below, assume you want to test code like the following:

* {C/C++}

  ```cpp
  class Parser {
    Parser(const std::string &name, uint32_t flags);
    virtual ~Parser();
    int Parse(const uint8 *buf, size_t len);
  };
  ```

* {Rust}

  ```rust
  struct ToyStruct {
      n: u8,
      s: String,
  }

  fn toy_example(input: ToyStruct) -> Result<u8, &'static str>;
  ```

* {Go}

  ```golang
  package mypackage

  func HandleBytes(s []byte) {
    // Complicated code goes here
  }

  type MyStruct struct {
    // Various fields
  }

  func HandleStruct(s MyStruct) {
    // Complicated code goes here
  }
  ```

## Simple Fuzz Target Function {#basic}

For each language, your fuzz target function will use the bytes provided to call the code you want
to fuzz. If the interface being fuzzed has documented constraints on its parameters, you can reject
inputs that don't meet those constraints. You can also ignore returned errors since failing
gracefully on invalid parameters is correct behavior.

* {C/C++}

  For C and C++, the fuzz target function must be have the signatue
  `extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)` and return 0:

  ```cpp
  extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    Parser parser("", 0);
    if (size < 5) {
      return 0;
    }
    parser.Parse(data, size);
    return 0;
  }
  ```

  Place this code in a source file adjacent to code being fuzzed as you would with a unit test. For
  example, the code above might be in `parser-fuzztest.cc`.

* {Rust}

  For Rust, the recommended approach is to use the `Arbitrary` trait discussed in the next section.

  It is also possible to create a "manual" fuzz target function that is analgous to the simple fuzz
  target functions in other languages. This function must take a reference to a byte slice as its
  single parameter, return nothing, and have the [`#[fuzz]`][fuzz-crate] attribute:

  ```rust
  use fuzz::fuzz;

  #[fuzz]
  fn toy_example_u8(input: &[u8]) {
      if input.len() == 0 {
          return
      }
      let n = input[0];
      if let Ok(s) = std::str::from_utf8(input[1:]) {
          let _ = toy_example(ToyStruct{n, s: s.to_string(),});
      }
  }
  ```

  As with unit tests, this code can be place in the same file as the code it is testing. For
  example, the code above might be in `toy_example/src/lib.rs`.

* {Go}

  For Go the fuzz target function must have the signature `func Fuzz(s []byte)` and return nothing.

  ```golang
  func Fuzz(s []byte) {
    mypackage.HandleBytes(s)
  }
  ```

  This function can be added to and exported from either an existing Go package, or a new Go package
  if no existing package is a good fit.

## Support for Fuzzing More Complex Types {#advanced}

Each language has utilities to facilitate making more complicated fuzz target functions:

* {C/C++}

  The [`FuzzedDataProvider`][fuzzed-data-provider] class provided by LLVM can help you map portions
  of the provided `data` to more complex types.

  For example:

  ```cpp
    #include <fuzzer/FuzzedDataProvider.h>

    extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
      FuzzedDataProvider provider(data, size);
      auto flags = provider.ConsumeIntegral<uint32_t>();
      auto name = provider.ConsumeRandomLengthString();
      Parser parser(name, flags);
      auto buf = provider.ConsumeRemainingBytes<uint8_t>();
      parser.Parse(buf.data(), buf.size());
      return 0;
    }
  ```

  There are two notable advantages to using this library:

   * First, it makes it easier to rapidly write a fuzzer.
   * Second, it is designed to dynamically split inputs in such a way that the fuzzer can
     efficiently create new inputs from coverage data.

  There is one notable disadvantage:

   * Since inputs are dynamically split, it is more difficult to provide a pre-existing [corpus]. It
     is still feasible to provide a [dictionary].

* {Rust}

  You can create a fuzz target function that takes one or more inputs with the `Arbitrary` trait
  from the [`arbitrary`][arbitrary] crate. This is the recommended approach.

  To write a fuzz target function that automatically transforms arbitrary inputs:

  1. If needed, implement the `Arbitrary` trait for the types used by your test code. If possible,
     the recommended way to do this is by automatically deriving the trait. Otherwise, this can be
     done "by hand" by following the crate's [instructions][arbitrary].

     For example, in your `src/lib.rs`:

     ```rust
     use arbitrary:Arbitrary;

     #[derive(Arbitrary)]
     struct ToyStruct { ... }
     ```

  1. Create a function with the [`#[fuzz]`][fuzz-crate] attribute that passes the necessary
     parameters to the code you wish to test.

     For example, in your `src/lib.rs`:

     ```rust
     use fuzz::fuzz;

     #[fuzz]
     fn toy_example_arbitrary(input: ToyStruct) {
         let _ = toy_example(input);
     }
     ```

* {Go}

  You can use the ["encoding/binary"][binary-encoding] package to "cast" or transform bytes to fixed
  size types:

  ```golang
  import (
    "bytes"
    "encoding/binary"
  )

  func Fuzz(s []byte) {
    var s MyStruct
    buf := bytes.NewReader(b)
    if err := binary.Read(buf, binary.LittleEndian, &s); err != nil {
      return
    }
    mypackage.HandleStruct(s)
  }
  ```

Next, you can [build](build-a-fuzzer.md) your newly created fuzzer using GN and Ninja.

[arbitrary]: https://docs.rs/arbitrary/0.4.0/arbitrary
[binary-encoding]: https://golang.org/pkg/encoding/binary/#Read
[corpus]: https://llvm.org/docs/LibFuzzer.html#corpus
[dictionary]: https://llvm.org/docs/LibFuzzer.html#dictionaries
[fuzz-crate]: /src/lib/fuzzing/rust/src/lib.rs
[fuzz-target]: https://llvm.org/docs/LibFuzzer.html#fuzz-target
[fuzzed-data-provider]: https://github.com/google/fuzzing/blob/HEAD/docs/split-inputs.md#fuzzed-data-provider
