Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions crates/movy-fuzz/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ pub struct SuiFuzzExecutor<T, OT, RT, I, S> {
// pub minted_gas: Object,
// pub log_tracer: Option<SuiLogTracer>,
pub ph: PhantomData<(I, S)>,
pub disable_oracles: bool,
pub epoch: u64,
pub epoch_ms: u64,
}
Expand Down Expand Up @@ -202,9 +201,7 @@ where
if !oracle_vulns.is_empty() {
trace_outcome.findings.extend(oracle_vulns.iter().cloned());
}
let kind = if self.disable_oracles {
ExitKind::Ok
} else if !oracle_vulns.is_empty() {
let kind = if !oracle_vulns.is_empty() {
ExitKind::Crash
} else {
trace_outcome.verdict
Expand Down
2 changes: 1 addition & 1 deletion crates/movy-fuzz/src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ fn collect_target_functions(
let mut target_functions: Vec<FunctionIdent> = vec![];

for package_addr in target_packages.iter() {
let Some(package_meta) = base.get_package_metadata(package_addr) else {
let Some(package_meta) = base.get_original_package_metadata(package_addr) else {
continue;
};
for module in package_meta.modules.iter() {
Expand Down
43 changes: 32 additions & 11 deletions crates/movy-fuzz/src/operations/sui_fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,23 @@ use movy_types::error::MovyError;
use sui_types::storage::BackingStore;
use sui_types::storage::{BackingPackageStore, ObjectStore};

pub fn oracles<T, S, E>(disabled: bool) -> impl for<'a> SuiGeneralOracle<CachedStore<&'a T>, S>
pub fn oracles<T, S, E>(
typed_bug_abort: bool,
disable_profit_oracle: bool,
disable_defects_oracle: bool,
) -> impl for<'a> SuiGeneralOracle<CachedStore<&'a T>, S>
where
T: 'static + ObjectStore,
S: HasMetadata + HasExtraState<ExtraState = ExtraNonSerdeFuzzState<E>> + HasFuzzMetadata,
{
tuple_list!(
CouldDisabledOralce::new(BoolJudgementOracle, disabled),
CouldDisabledOralce::new(InfiniteLoopOracle::default(), disabled),
CouldDisabledOralce::new(PrecisionLossOracle, disabled),
CouldDisabledOralce::new(TypeConversionOracle, disabled),
CouldDisabledOralce::new(OverflowOracle, disabled),
CouldDisabledOralce::new(ProceedsOracle::default(), disabled),
CouldDisabledOralce::new(TypedBugOracle, disabled),
CouldDisabledOralce::new(BoolJudgementOracle, disable_defects_oracle),
CouldDisabledOralce::new(InfiniteLoopOracle::default(), disable_defects_oracle),
CouldDisabledOralce::new(PrecisionLossOracle, disable_defects_oracle),
CouldDisabledOralce::new(TypeConversionOracle, disable_defects_oracle),
CouldDisabledOralce::new(OverflowOracle, disable_defects_oracle),
CouldDisabledOralce::new(ProceedsOracle::default(), disable_profit_oracle),
CouldDisabledOralce::new(TypedBugOracle::new(typed_bug_abort), disable_defects_oracle),
)
}

Expand All @@ -56,6 +60,9 @@ fn fuzz_impl<T>(
env: SuiTestingEnv<T>,
output: &Option<PathBuf>,
time_limit: Option<u64>,
typed_bug_abort: bool,
disable_profit_oracle: bool,
disable_defects_oracle: bool,
) -> Result<(), MovyError>
where
T: ObjectStoreCachedStore
Expand Down Expand Up @@ -124,8 +131,11 @@ where
executor: executor_inner,
ob: tuple_list!(code_observer),
attacker,
oracles: oracles(true),
disable_oracles: false,
oracles: oracles(
typed_bug_abort,
disable_profit_oracle,
disable_defects_oracle,
),
epoch: state.fuzz_state().epoch,
epoch_ms: state.fuzz_state().epoch_ms,
ph: std::marker::PhantomData,
Expand Down Expand Up @@ -240,7 +250,18 @@ pub fn fuzz(
>,
output: &Option<PathBuf>,
time_limit: Option<u64>,
typed_bug_abort: bool,
disable_profit_oracle: bool,
disable_defects_oracle: bool,
) -> Result<(), MovyError> {
fuzz_impl(meta, env, output, time_limit)?;
fuzz_impl(
meta,
env,
output,
time_limit,
typed_bug_abort,
disable_profit_oracle,
disable_defects_oracle,
)?;
Ok(())
}
3 changes: 1 addition & 2 deletions crates/movy-fuzz/src/operations/sui_replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ where
executor: executor_inner,
ob: tuple_list!(code_observer),
attacker,
oracles: super::sui_fuzz::oracles(false),
disable_oracles: false,
oracles: super::sui_fuzz::oracles(false, false, false),
epoch: state.fuzz_state().epoch,
epoch_ms: state.fuzz_state().epoch_ms,
ph: std::marker::PhantomData,
Expand Down
47 changes: 43 additions & 4 deletions crates/movy-fuzz/src/oracles/sui/typed_bug.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
use log::debug;
use log::{debug, trace};
use move_trace_format::format::TraceEvent;
use move_vm_stack::Stack;

use movy_replay::tracer::{concolic::ConcolicState, oracle::SuiGeneralOracle};
use movy_types::{error::MovyError, input::MoveSequence, oracle::OracleFinding};
use serde_json::json;
use sui_types::{effects::TransactionEffects, storage::ObjectStore};
use sui_types::{
effects::{TransactionEffects, TransactionEffectsAPI},
execution_status::{ExecutionFailureStatus, ExecutionStatus},
storage::ObjectStore,
};

use crate::{
meta::HasFuzzMetadata,
state::{ExtraNonSerdeFuzzState, HasExtraState},
};

#[derive(Debug, Default, Clone)]
pub struct TypedBugOracle;
const TYPED_BUG_ABORT_CODE: u64 = 19260817;

#[derive(Debug, Clone)]
pub struct TypedBugOracle {
pub use_abort: bool,
}

impl Default for TypedBugOracle {
fn default() -> Self {
Self { use_abort: false }
}
}

impl TypedBugOracle {
pub fn new(use_abort: bool) -> Self {
Self { use_abort }
}
}

impl<T, S, E> SuiGeneralOracle<T, S> for TypedBugOracle
where
Expand Down Expand Up @@ -46,6 +66,25 @@ where
state: &mut S,
_effects: &TransactionEffects,
) -> Result<Vec<OracleFinding>, MovyError> {
trace!("TypedBugOracle done_execution called");
if self.use_abort {
match _effects.status() {
ExecutionStatus::Failure {
error: ExecutionFailureStatus::MoveAbort(_, code),
..
} if *code == TYPED_BUG_ABORT_CODE => {
debug!("Typed bug abort detected: code {}", code);
return Ok(vec![OracleFinding {
oracle: "TypedBugOracle".to_string(),
severity: movy_types::oracle::Severity::Critical,
extra: json!({
"abort_code": code,
}),
}]);
}
_ => return Ok(Vec::new()),
}
}
let Some(global_outcome) = state.extra_state().global_outcome.as_ref() else {
return Ok(Vec::new());
};
Expand Down
28 changes: 27 additions & 1 deletion crates/movy/src/sui/fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,24 @@ pub struct SuiFuzzArgs {
pub target: SuiTargetArgs,
#[clap(flatten)]
pub filters: FuzzTargetArgs,
#[arg(
long,
help = "Detect typed bug via abort code 19260817 instead of oracle event",
default_value_t = false
)]
pub typed_bug_abort: bool,
#[arg(
long,
help = "Disable profit oracle (ProceedsOracle)",
default_value_t = false
)]
pub disable_profit_oracle: bool,
#[arg(
long,
help = "Disable defect oracles (others including typed bug event-based checks)",
default_value_t = false
)]
pub disable_defects_oracle: bool,
}

impl SuiFuzzArgs {
Expand Down Expand Up @@ -264,7 +282,15 @@ impl SuiFuzzArgs {
tokio::task::spawn_blocking(move || {
let inner = testing_env.into_inner();
let env = SuiTestingEnv::new(Arc::new(inner));
sui_fuzz::fuzz(meta, env, &self.output, self.time_limit)
sui_fuzz::fuzz(
meta,
env,
&self.output,
self.time_limit,
self.typed_bug_abort,
self.disable_profit_oracle,
self.disable_defects_oracle,
)
})
.await??;
Ok(())
Expand Down