chromium/components/zucchini/fuzzers/BUILD.gn

# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//testing/libfuzzer/fuzzer_test.gni")
import("//third_party/protobuf/proto_library.gni")

static_library("zucchini_fuzz_utils") {
  sources = [
    "fuzz_utils.cc",
    "fuzz_utils.h",
  ]
  deps = [
    "//base",
    "//components/zucchini:zucchini_lib",
  ]
}

# To download the corpus for local fuzzing use:
# gsutil -m rsync \
#   gs://clusterfuzz-corpus/libfuzzer/zucchini_disassembler_dex_fuzzer \
#   components/zucchini/fuzzing/testdata/disassembler_dex_fuzzer/
fuzzer_test("zucchini_disassembler_dex_fuzzer") {
  sources = [ "disassembler_dex_fuzzer.cc" ]
  deps = [
    "//base",
    "//components/zucchini:zucchini_lib",
  ]
}

# To download the corpus for local fuzzing use:
# gsutil -m rsync \
#   gs://clusterfuzz-corpus/libfuzzer/zucchini_disassembler_win32_fuzzer \
#   components/zucchini/fuzzing/testdata/disassembler_win32_fuzzer/
fuzzer_test("zucchini_disassembler_win32_fuzzer") {
  sources = [ "disassembler_win32_fuzzer.cc" ]
  deps = [
    ":zucchini_fuzz_utils",
    "//base",
    "//components/zucchini:zucchini_lib",
  ]
}

# To download the corpus for local fuzzing use:
# gsutil -m rsync \
#   gs://clusterfuzz-corpus/libfuzzer/zucchini_disassembler_elf_fuzzer \
#   components/zucchini/fuzzing/testdata/disassembler_elf_fuzzer/
fuzzer_test("zucchini_disassembler_elf_fuzzer") {
  sources = [ "disassembler_elf_fuzzer.cc" ]
  deps = [
    ":zucchini_fuzz_utils",
    "//base",
    "//components/zucchini:zucchini_lib",
  ]
}

fuzzer_test("zucchini_patch_fuzzer") {
  sources = [ "patch_fuzzer.cc" ]
  deps = [
    "//base",
    "//components/zucchini:zucchini_lib",
  ]
  seed_corpus = "testdata/patch_fuzzer"
}

proto_library("zucchini_file_pair_proto") {
  sources = [ "file_pair.proto" ]
}

# Ensure protoc is available.
# Disabled on Windows due to crbug/844826.
if (current_toolchain == host_toolchain && !is_win) {
  # Raw Apply Fuzzer Seed:
  action("zucchini_raw_apply_seed") {
    script = "generate_fuzzer_data.py"

    args = [
      "--raw",
      "old_eventlog_provider.dll",  # <old_file>
      "new_eventlog_provider.dll",  # <new_file>

      # <patch_file> (temporary)
      rebase_path(
          "$target_gen_dir/testdata/apply_fuzzer/eventlog_provider.patch",
          root_build_dir),

      # <output_file>
      rebase_path(
          "$target_gen_dir/testdata/apply_fuzzer/raw_apply_seed_proto.bin",
          root_build_dir),
    ]

    # Files depended upon.
    sources = [
      "create_seed_file_pair.py",
      "testdata/new_eventlog_provider.dll",
      "testdata/old_eventlog_provider.dll",
    ]

    # Outputs: necessary for validation.
    outputs =
        [ "$target_gen_dir/testdata/apply_fuzzer/raw_apply_seed_proto.bin" ]
    deps = [
      "//components/zucchini:zucchini",
      "//third_party/protobuf:protoc",
    ]
  }

  # ZTF Apply Fuzzer Seed:
  action("zucchini_ztf_apply_seed") {
    script = "generate_fuzzer_data.py"

    # *.ztf files are expected to be valid ZTF format.
    args = [
      "old.ztf",  # <old_file>
      "new.ztf",  # <new_file>

      # <patch_file> (temporary)
      rebase_path("$target_gen_dir/testdata/apply_fuzzer/ztf.patch",
                  root_build_dir),

      # <output_file>
      rebase_path(
          "$target_gen_dir/testdata/apply_fuzzer/ztf_apply_seed_proto.bin",
          root_build_dir),
    ]

    # Files depended upon.
    sources = [
      "create_seed_file_pair.py",
      "testdata/new.ztf",
      "testdata/old.ztf",
    ]

    # Outputs: necessary for validation.
    outputs =
        [ "$target_gen_dir/testdata/apply_fuzzer/ztf_apply_seed_proto.bin" ]
    deps = [
      "//components/zucchini:zucchini",
      "//third_party/protobuf:protoc",
    ]
  }

  # Apply Fuzzer:
  fuzzer_test("zucchini_apply_fuzzer") {
    sources = [ "apply_fuzzer.cc" ]
    deps = [
      ":zucchini_file_pair_proto",
      "//base",
      "//components/zucchini:zucchini_lib",
      "//third_party/libprotobuf-mutator",
    ]
    seed_corpus = "$target_gen_dir/testdata/apply_fuzzer"
    seed_corpus_deps = [
      ":zucchini_raw_apply_seed",
      ":zucchini_ztf_apply_seed",
    ]
  }

  # For Gen fuzzers seeds can be created from this directory with:
  # python create_seed_file_pair.py <protoc> <old file> <new file> <out file>
  #   [--imposed=<imposed>]

  # Raw Gen Fuzzer:
  # <old file>: testdata/old.ztf
  # <new file>: testdata/new.ztf
  # <out file>: testdata/raw_or_ztf_gen_fuzzer/seed.asciipb
  fuzzer_test("zucchini_raw_gen_fuzzer") {
    sources = [ "raw_gen_fuzzer.cc" ]
    deps = [
      ":zucchini_file_pair_proto",
      "//base",
      "//components/zucchini:zucchini_lib",
      "//third_party/libprotobuf-mutator",
    ]
    seed_corpus = "testdata/raw_or_ztf_gen_fuzzer"
  }

  # ZTF Gen Fuzzer:
  # <old file>: testdata/old.ztf
  # <new file>: testdata/new.ztf
  # <out file>: testdata/raw_or_ztf_gen_fuzzer/seed.asciipb
  fuzzer_test("zucchini_ztf_gen_fuzzer") {
    sources = [ "ztf_gen_fuzzer.cc" ]
    deps = [
      ":zucchini_file_pair_proto",
      "//base",
      "//components/zucchini:zucchini_lib",
      "//third_party/libprotobuf-mutator",
    ]
    seed_corpus = "testdata/raw_or_ztf_gen_fuzzer"
  }

  # Imposed Ensemble Match Fuzzer:
  # <old file>: testdata/old_imposed_archive.txt
  # <new file>: testdata/new_imposed_archive.txt
  # <out file>: testdata/imposed_ensemble_matcher_fuzzer/seed.asciipb
  # <imposed>: 17+420=388+347,452+420=27+347
  # This is a mapping of regions old_offset+old_size=new_offset+new_size,...
  fuzzer_test("zucchini_imposed_ensemble_matcher_fuzzer") {
    sources = [ "imposed_ensemble_matcher_fuzzer.cc" ]
    deps = [
      ":zucchini_file_pair_proto",
      "//base",
      "//components/zucchini:zucchini_lib",
      "//third_party/libprotobuf-mutator",
    ]
    seed_corpus = "testdata/imposed_ensemble_matcher_fuzzer"
  }
}