aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalder Kitagawa <ckitagawa@chromium.org>2018-07-03 14:30:05 +0000
committerCopybara-Service <copybara-worker@google.com>2021-07-25 20:04:34 -0700
commit9ee7e438c02c3190f503bad3ffb15d6e1f507246 (patch)
tree62e7e4c9f5f16e3f247c32fafc0fc4fdd2595e40
parent61784804c0ff95bd91a17f74808e0fd1a3af9266 (diff)
downloadzucchini-9ee7e438c02c3190f503bad3ffb15d6e1f507246.tar.gz
[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 <ckitagawa@chromium.org> Reviewed-by: Greg Thompson <grt@chromium.org> Cr-Commit-Position: refs/heads/master@{#572203} NOKEYCHECK=True GitOrigin-RevId: c2a778621cbcd812e2687269ba3f10132a31df12
-rw-r--r--BUILD.gn1
-rw-r--r--fuzzers/BUILD.gn14
-rw-r--r--fuzzers/disassembler_dex_fuzzer.cc53
3 files changed, 68 insertions, 0 deletions
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
@@ -7,6 +7,20 @@ 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 \
# components/zucchini/fuzzing/testdata/disassembler_win32_fuzzer
fuzzer_test("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 <stddef.h>
+#include <stdint.h>
+
+#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<uint8_t> 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::DisassemblerDex>(
+ zucchini::ConstBufferView(mutable_image));
+ if (!disassembler_dex)
+ return 0;
+
+ std::vector<zucchini::Reference> 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;
+}