From 9ee7e438c02c3190f503bad3ffb15d6e1f507246 Mon Sep 17 00:00:00 2001 From: Calder Kitagawa Date: Tue, 3 Jul 2018 14:30:05 +0000 Subject: [Zucchini] Add dissassembler_dex Fuzzer Adds a fuzzer for disassembly of DEX files. This achieves ~7500 exec/s and covers 97% of files of interest in 10000 runs. The bulk of the uncovered code is writers which require a patch file and this is more complex and expensive to fuzz so like the Windows Disassembler we will hold off on fuzzing this for now. The source seed for fuzzing is the WebAPK shell app and is uploaded to the Fuzzing GCS bucket as it is on the larger side. See: zucchini_disassembler_dex_fuzzer_static Bug: 835341 Change-Id: I40651286b571964b719ca61074d5e35934e88189 Reviewed-on: https://chromium-review.googlesource.com/1117123 Commit-Queue: Calder Kitagawa Reviewed-by: Greg Thompson Cr-Commit-Position: refs/heads/master@{#572203} NOKEYCHECK=True GitOrigin-RevId: c2a778621cbcd812e2687269ba3f10132a31df12 --- BUILD.gn | 1 + fuzzers/BUILD.gn | 14 ++++++++++ fuzzers/disassembler_dex_fuzzer.cc | 53 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 fuzzers/disassembler_dex_fuzzer.cc diff --git a/BUILD.gn b/BUILD.gn index 9555d9e..77dc810 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -212,6 +212,7 @@ test("zucchini_integration_test") { group("zucchini_fuzzers") { testonly = true deps = [ + "//components/zucchini/fuzzers:zucchini_disassembler_dex_fuzzer", "//components/zucchini/fuzzers:zucchini_disassembler_win32_fuzzer", "//components/zucchini/fuzzers:zucchini_patch_fuzzer", ] diff --git a/fuzzers/BUILD.gn b/fuzzers/BUILD.gn index 10a8bba..12964f3 100644 --- a/fuzzers/BUILD.gn +++ b/fuzzers/BUILD.gn @@ -5,6 +5,20 @@ import("//testing/libfuzzer/fuzzer_test.gni") import("//third_party/protobuf/proto_library.gni") +# 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 \ diff --git a/fuzzers/disassembler_dex_fuzzer.cc b/fuzzers/disassembler_dex_fuzzer.cc new file mode 100644 index 0000000..5968c98 --- /dev/null +++ b/fuzzers/disassembler_dex_fuzzer.cc @@ -0,0 +1,53 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "base/logging.h" +#include "components/zucchini/buffer_view.h" +#include "components/zucchini/disassembler.h" +#include "components/zucchini/disassembler_dex.h" + +namespace { + +struct Environment { + Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); } +}; + +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static Environment env; + if (!size) + return 0; + // Prepare data. + std::vector mutable_data(data, data + size); + zucchini::MutableBufferView mutable_image(mutable_data.data(), + mutable_data.size()); + + // Create disassembler. Early exit on failure. + auto disassembler_dex = + zucchini::Disassembler::Make( + zucchini::ConstBufferView(mutable_image)); + if (!disassembler_dex) + return 0; + + std::vector references; + // Read all references in the file. + auto groups = disassembler_dex->MakeReferenceGroups(); + for (const auto& group : groups) { + auto reader = group.GetReader(disassembler_dex.get()); + for (auto ref = reader->GetNext(); ref.has_value(); + ref = reader->GetNext()) { + references.push_back(ref.value()); + } + reader.reset(); + auto writer = group.GetWriter(mutable_image, disassembler_dex.get()); + for (const auto& ref : references) + writer->PutNext(ref); + references.clear(); + } + return 0; +} -- cgit v1.2.3