Skip to content

Commit

Permalink
add CompiledModule and CompiledScript deserializer fuzzer (#15494)
Browse files Browse the repository at this point in the history
* add CompiledModule and CompiledScript deserializer fuzzer
  • Loading branch information
gedigi authored Dec 10, 2024
1 parent e8289d1 commit 6dbfb31
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
20 changes: 15 additions & 5 deletions testsuite/fuzzer/fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,22 @@ function build-oss-fuzz() {
done
}

function install-coverage-tools() {
cargo +$NIGHTLY_VERSION install cargo-binutils
cargo +$NIGHTLY_VERSION install rustfilt
}

function coverage() {
if [ -z "$1" ]; then
usage coverage
fi
fuzz_target=$1

if ! cargo +$NIGHTLY_VERSION cov -V &> /dev/null; then
install-coverage-tools
fi

clean-coverage $fuzz_target
local corpus_dir="fuzz/corpus/$fuzz_target"
local coverage_dir="./fuzz/coverage/$fuzz_target/report"
mkdir -p $coverage_dir
Expand All @@ -184,7 +195,7 @@ function coverage() {
fuzz_target_bin=$(find ./target/*/coverage -name $fuzz_target -type f -perm /111) #$(find target/*/coverage -name $fuzz_target -type f)
echo "Found fuzz target binary: $fuzz_target_bin"
# Generate the coverage report
cargo +nightly cov -- show $fuzz_target_bin \
cargo +$NIGHTLY_VERSION cov -- show $fuzz_target_bin \
--format=html \
--instr-profile=fuzz/coverage/$fuzz_target/coverage.profdata \
--show-directory-coverage \
Expand All @@ -200,12 +211,11 @@ function clean-coverage() {
fi

local fuzz_target="$1"
local coverage_dir="./fuzz/coverage/$fuzz_target/"

if [ "$fuzz_target" == "all" ]; then
rm -rf coverage
rm -rf ./fuzz/coverage
else
rm -rf $target_dir
local coverage_dir="./fuzz/coverage/$fuzz_target/"
rm -rf $coverage_dir
fi
}

Expand Down
6 changes: 6 additions & 0 deletions testsuite/fuzzer/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@ name = "use_case_aware_shuffler"
path = "fuzz_targets/use_case_aware_shuffler.rs"
test = false
doc = false

[[bin]]
name = "deserialize_script_module"
path = "fuzz_targets/move/deserialize_script_module.rs"
test = false
doc = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0

#![no_main]
use arbitrary::Arbitrary;
use libfuzzer_sys::{fuzz_target, Corpus};
// mod utils;
use move_binary_format::{
deserializer::DeserializerConfig, file_format::CompiledScript, CompiledModule,
};

#[derive(Arbitrary, Debug)]
enum ExecVariant {
Module(CompiledModule),
Script(CompiledScript),
Raw(Vec<u8>),
}

fuzz_target!(|fuzz_data: ExecVariant| -> Corpus { run_case(&fuzz_data) });

fn run_case(data: &ExecVariant) -> Corpus {
match data {
ExecVariant::Module(module) => run_case_module(module),
ExecVariant::Script(script) => run_case_script(script),
ExecVariant::Raw(raw_data) => run_case_raw(raw_data),
}
}

fn run_case_module(module: &CompiledModule) -> Corpus {
let mut module_code = vec![];
if module.serialize(&mut module_code).is_err() {
return Corpus::Reject;
}
match CompiledModule::deserialize_with_config(&module_code, &DeserializerConfig::default()) {
Ok(mut m) => {
m.version = module.version;
assert_eq!(*module, m);
Corpus::Keep
},
Err(_) => Corpus::Reject,
}
}

fn run_case_script(script: &CompiledScript) -> Corpus {
let mut script_code = vec![];
if script.serialize(&mut script_code).is_err() {
return Corpus::Reject;
}
match CompiledScript::deserialize_with_config(&script_code, &DeserializerConfig::default()) {
Ok(mut s) => {
s.version = script.version;
assert_eq!(*script, s);
Corpus::Keep
},
Err(_) => Corpus::Reject,
}
}

fn run_case_raw(raw_data: &Vec<u8>) -> Corpus {
if let Ok(m) = CompiledModule::deserialize_with_config(raw_data, &DeserializerConfig::default())
{
let mut module_code = vec![];
m.serialize(&mut module_code).unwrap();
assert_eq!(*raw_data, module_code);
return Corpus::Keep;
}

if let Ok(s) = CompiledScript::deserialize_with_config(raw_data, &DeserializerConfig::default())
{
let mut script_code = vec![];
s.serialize(&mut script_code).unwrap();
assert_eq!(*raw_data, script_code);
return Corpus::Keep;
}

Corpus::Reject
}

0 comments on commit 6dbfb31

Please sign in to comment.