aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalder Kitagawa <ckitagawa@chromium.org>2018-05-28 14:30:21 +0000
committerEdward Lesmes <ehmaldonado@google.com>2021-07-23 22:43:11 +0000
commit806fa630e61962fc2093be31eb3fad5fa745a27c (patch)
tree748f363f9ade33e7c598587e3e6ae5b98a61d079
parent75569ad9940020e9730359c52bad857be7690025 (diff)
downloadzucchini-806fa630e61962fc2093be31eb3fad5fa745a27c.tar.gz
[Zucchini] ZTF Apply Fuzzer
This is part of a series of Fuzzers to be added to Zucchini for security review. This tests the full patch application logic exercising the patch reader and apply process. It covers ~33% of code in 1000000 runs. The bulk of remaining code ~40% is covered by ZTF Gen Fuzzer. With the remainder (~30%) being for DEX Disassembly (not in launch scope), patch serialization (trusted input), and other testing/debugging/error handling code which isn't triggered. This already found a couple bugs fixed in https://chromium-review.googlesource.com/c/chromium/src/+/1072272 With the supplied seed corpus the fuzzer reaches approximately 12000 execs/s. The file format for the seed is a FilePair proto of a ZTF base file and a patch file as used in Raw Apply. This reuses the same generator and fuzzer as Raw Apply as the type of application is encoded in the patch itself. Bug: 835341 Change-Id: I00f28c768a6e1c7b8c5e95979b279d64785ef515 Reviewed-on: https://chromium-review.googlesource.com/1072231 Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org> Reviewed-by: Samuel Huang <huangs@chromium.org> Reviewed-by: Max Moroz <mmoroz@chromium.org> Cr-Commit-Position: refs/heads/master@{#562260} NOKEYCHECK=True GitOrigin-RevId: 7206487ebd05fd4f30226ec59b730bb41c5013f2
-rw-r--r--BUILD.gn2
-rw-r--r--fuzzers/BUILD.gn55
-rw-r--r--fuzzers/apply_fuzzer.cc (renamed from fuzzers/raw_apply_fuzzer.cc)2
-rwxr-xr-xfuzzers/generate_fuzzer_data.py10
-rw-r--r--fuzzers/testdata/new.ztf (renamed from fuzzers/testdata/new.ztxt)0
-rw-r--r--fuzzers/testdata/old.ztf (renamed from fuzzers/testdata/old.ztxt)0
6 files changed, 54 insertions, 15 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 7eb9c74..9f7318a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -221,7 +221,7 @@ group("zucchini_fuzzers") {
# Disabled on Windows due to crbug/844826.
if (current_toolchain == host_toolchain && !is_win) {
deps += [
- "//components/zucchini/fuzzers:zucchini_raw_apply_fuzzer",
+ "//components/zucchini/fuzzers:zucchini_apply_fuzzer",
"//components/zucchini/fuzzers:zucchini_raw_gen_fuzzer",
"//components/zucchini/fuzzers:zucchini_ztf_gen_fuzzer",
]
diff --git a/fuzzers/BUILD.gn b/fuzzers/BUILD.gn
index e11efc4..51680c3 100644
--- a/fuzzers/BUILD.gn
+++ b/fuzzers/BUILD.gn
@@ -39,7 +39,7 @@ proto_library("zucchini_file_pair_proto") {
# Ensure protoc is available.
# Disabled on Windows due to crbug/844826.
if (current_toolchain == host_toolchain && !is_win) {
- # Raw Apply Fuzzer:
+ # Raw Apply Fuzzer Seed:
action("zucchini_raw_apply_seed") {
script = "generate_fuzzer_data.py"
@@ -49,8 +49,10 @@ if (current_toolchain == host_toolchain && !is_win) {
"new_eventlog_provider.dll", # <new_file>
"eventlog_provider.patch", # <patch_file> (temporary)
- # <output_dir>
- rebase_path("$target_gen_dir/testdata/raw_apply_fuzzer", root_build_dir),
+ # <output_file>
+ rebase_path(
+ "$target_gen_dir/testdata/apply_fuzzer/raw_apply_seed_proto.bin",
+ root_build_dir),
]
# Files depended upon.
@@ -62,7 +64,7 @@ if (current_toolchain == host_toolchain && !is_win) {
# Outputs: necessary for validation.
outputs = [
- "$target_gen_dir/testdata/raw_apply_fuzzer/seed_proto.bin",
+ "$target_gen_dir/testdata/apply_fuzzer/raw_apply_seed_proto.bin",
]
deps = [
"//components/zucchini:zucchini",
@@ -70,9 +72,43 @@ if (current_toolchain == host_toolchain && !is_win) {
]
}
- fuzzer_test("zucchini_raw_apply_fuzzer") {
+ # 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>
+ "ztf.patch", # <patch_file> (temporary)
+
+ # <output_file>
+ rebase_path(
+ "$target_gen_dir/testdata/apply_fuzzer/ztf_apply_seed_proto.bin",
+ root_build_dir),
+ ]
+
+ # Files depended upon.
sources = [
- "raw_apply_fuzzer.cc",
+ "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",
@@ -80,8 +116,11 @@ if (current_toolchain == host_toolchain && !is_win) {
"//components/zucchini:zucchini_lib",
"//third_party/libprotobuf-mutator",
]
- seed_corpus = "$target_gen_dir/testdata/raw_apply_fuzzer"
- seed_corpus_deps = [ ":zucchini_raw_apply_seed" ]
+ seed_corpus = "$target_gen_dir/testdata/apply_fuzzer"
+ seed_corpus_deps = [
+ ":zucchini_raw_apply_seed",
+ ":zucchini_ztf_apply_seed",
+ ]
}
# Raw Gen Fuzzer:
diff --git a/fuzzers/raw_apply_fuzzer.cc b/fuzzers/apply_fuzzer.cc
index da3230a..4e9b342 100644
--- a/fuzzers/raw_apply_fuzzer.cc
+++ b/fuzzers/apply_fuzzer.cc
@@ -18,7 +18,7 @@
struct Environment {
Environment() {
- logging::SetMinLogLevel(3); // Disable console spamming.
+ logging::SetMinLogLevel(logging::LOG_FATAL); // Disable console spamming.
}
};
diff --git a/fuzzers/generate_fuzzer_data.py b/fuzzers/generate_fuzzer_data.py
index c182baf..5a22109 100755
--- a/fuzzers/generate_fuzzer_data.py
+++ b/fuzzers/generate_fuzzer_data.py
@@ -28,14 +28,14 @@ def parse_args():
parser.add_argument('old_file', help='Old file to generate/apply patch.')
parser.add_argument('new_file', help='New file to generate patch from.')
parser.add_argument('patch_file', help='Patch filename to use.')
- parser.add_argument('output_dir',
- help='Directory to write binary protobuf to.')
+ parser.add_argument('output_file', help='File to write binary protobuf to.')
return parser.parse_args()
-def gen(old_file, new_file, patch_file, output_dir, is_raw, is_win):
+def gen(old_file, new_file, patch_file, output_file, is_raw, is_win):
"""Generates a new patch and binary encodes a protobuf pair."""
# Create output directory if missing.
+ output_dir = os.path.dirname(output_file)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
@@ -61,7 +61,7 @@ def gen(old_file, new_file, patch_file, output_dir, is_raw, is_win):
ret = subprocess.call([sys.executable,
os.path.join(ABS_PATH, 'create_seed_file_pair.py'),
os.path.abspath(protoc), old_file, patch_file,
- os.path.join(output_dir, 'seed_proto.bin')],
+ output_file],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
os.remove(patch_file)
@@ -73,7 +73,7 @@ def main():
return gen(os.path.join(ABS_TESTDATA_PATH, args.old_file),
os.path.join(ABS_TESTDATA_PATH, args.new_file),
os.path.join(ABS_TESTDATA_PATH, args.patch_file),
- os.path.abspath(args.output_dir),
+ os.path.abspath(args.output_file),
args.raw,
platform.system() == 'Windows')
diff --git a/fuzzers/testdata/new.ztxt b/fuzzers/testdata/new.ztf
index 1b1876f..1b1876f 100644
--- a/fuzzers/testdata/new.ztxt
+++ b/fuzzers/testdata/new.ztf
diff --git a/fuzzers/testdata/old.ztxt b/fuzzers/testdata/old.ztf
index 12dd536..12dd536 100644
--- a/fuzzers/testdata/old.ztxt
+++ b/fuzzers/testdata/old.ztf