Skip to content

Commit

Permalink
Fuzzing Tooling: cmin and precise stack trace for PartialVMErrors (#1…
Browse files Browse the repository at this point in the history
…5739)

* Enhance fuzz.sh script with 'cmin' functionality for corpus minimization.
Introduce debug panic mechanism in errors.rs for improved error handling during fuzzing and update README.md for usage instructions.

* fmt

* rename
remove useless collect
  • Loading branch information
zi0Black authored Jan 19, 2025
1 parent 824511d commit b2b3d67
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
11 changes: 11 additions & 0 deletions testsuite/fuzzer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ The script includes several functions to manage and execute fuzz tests:
```bash
./fuzz.sh build-oss-fuzz <target_dir>
```
- `cmin`: Distillate corpora
```bash
./fuzz.sh cmin <fuzz_target> [corpora_directory]
```
- `coverage`: Generates coverage report in HTML format
```bash
./fuzz.sh coverage <fuzz_target>
Expand Down Expand Up @@ -124,6 +128,13 @@ The CSV file is structured as follows:
- Column 2: Module address
- Column 3: Base64-encoded bytecode of the module
## Debug Crashes
Flamegraph and GDB are integrated into fuzz.sh for advanced metrics and debugging. A more rudimentary option is also available: since we have symbolized binaries, we can directly use the stack trace produced by the fuzzer. However, for INVARIANT_VIOLATIONS, the stack trace is incorrect. To obtain the correct stack trace, you can use the following command:
```bash
DEBUG_VM_STATUS=<status_reported_by_the_fuzzer> ./fuzz.sh run <fuzzer_target> <test_case>
```
This command is selective, so only the specified, comma-separated statuses will trigger the panic in PartialVMError.
## References
- [Rust Fuzz Book](https://rust-fuzz.github.io/book/)
- [Google OSS-Fuzz](https://google.github.io/oss-fuzz/)
Expand Down
19 changes: 18 additions & 1 deletion testsuite/fuzzer/fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ function usage() {
"build-oss-fuzz")
echo "Usage: $0 build-oss-fuzz <target_dir>"
;;
"cmin")
echo "Usage: $0 cmin <fuzz_target> [corpus_dir]"
;;
"coverage")
echo "Usage: $0 coverage <fuzz_target>"
;;
Expand Down Expand Up @@ -80,6 +83,7 @@ function usage() {
echo " block-builder runs rust tool to hel build fuzzers"
echo " build builds fuzz targets"
echo " build-oss-fuzz builds fuzz targets for oss-fuzz"
echo " cmin minimizes a corpus for a target"
echo " coverage generates coverage for a fuzz target"
echo " clean-coverage clean coverage for a fuzz target"
echo " debug debugs a fuzz target with a testcase"
Expand Down Expand Up @@ -166,6 +170,15 @@ function build-oss-fuzz() {
done
}

function cmin() {
if [ -z "$1" ]; then
usage cmin
fi
fuzz_target=$1
corpus_dir=${2:-./fuzz/corpus/$fuzz_target}
cargo_fuzz cmin $fuzz_target $corpus_dir
}

function install-coverage-tools() {
cargo +$NIGHTLY_VERSION install cargo-binutils
cargo +$NIGHTLY_VERSION install rustfilt
Expand Down Expand Up @@ -271,7 +284,7 @@ function run() {
fi
fi
info "Running $fuzz_target"
cargo_fuzz run --sanitizer none -O $fuzz_target $testcase -- -fork=10
cargo_fuzz run --sanitizer address -O $fuzz_target $testcase -- -fork=15 #-ignore_crashes=1
}

function test() {
Expand Down Expand Up @@ -340,6 +353,10 @@ case "$1" in
shift
build-oss-fuzz "$@"
;;
"cmin")
shift
cmin "$@"
;;
"coverage")
shift
coverage "$@"
Expand Down
21 changes: 21 additions & 0 deletions third_party/move/move-binary-format/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ pub type VMResult<T> = ::std::result::Result<T, VMError>;
pub type BinaryLoaderResult<T> = ::std::result::Result<T, PartialVMError>;
pub type PartialVMResult<T> = ::std::result::Result<T, PartialVMError>;

/// This macro is used to panic while debugging fuzzing crashes obtaining the right stack trace.
/// e.g. DEBUG_VM_STATUS=ABORTED,UNKNOWN_INVARIANT_VIOLATION_ERROR ./fuzz.sh run move_aptosvm_publish_and_run <testcase>
/// third_party/move/move-core/types/src/vm_status.rs:506 for the list of status codes.
#[cfg(feature = "fuzzing")]
macro_rules! fuzzing_maybe_panic {
($major_status:expr, $message:expr) => {{
if let Ok(debug_statuses) = std::env::var("DEBUG_VM_STATUS") {
if debug_statuses
.split(',')
.any(|s| s.trim() == format!("{:?}", $major_status))
{
panic!("PartialVMError: {:?} {:?}", $major_status, $message);
}
}
}};
}

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Location {
Undefined,
Expand Down Expand Up @@ -438,6 +455,10 @@ impl PartialVMError {
} else {
None
};

#[cfg(feature = "fuzzing")]
fuzzing_maybe_panic!(major_status, message);

Self(Box::new(PartialVMError_ {
major_status,
sub_status: None,
Expand Down

0 comments on commit b2b3d67

Please sign in to comment.