Skip to content

Commit 147ba5d

Browse files
authored
Merge pull request #11 from BitsLabSec/several_fixes
Several fixes
2 parents 2c0662a + d08982c commit 147ba5d

7 files changed

Lines changed: 55 additions & 16 deletions

File tree

crates/movy-analysis/src/type_graph.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use std::{
44
};
55

66
use movy_types::abi::{
7-
MoveAbiSignatureToken, MoveFunctionAbi, MoveModuleAbi, MoveModuleId, MovePackageAbi,
7+
MoveAbiSignatureToken, MoveFunctionAbi, MoveFunctionVisibility, MoveModuleAbi, MoveModuleId,
8+
MovePackageAbi,
89
};
910
use petgraph::{graph::NodeIndex, visit::EdgeRef};
1011
use serde::{Deserialize, Serialize};
@@ -126,6 +127,7 @@ impl MoveTypeGraph {
126127
pub fn find_consumers(
127128
&self,
128129
ty: &MoveAbiSignatureToken,
130+
public_only: bool,
129131
) -> Vec<(&MoveModuleId, &MoveFunctionAbi)> {
130132
let mut consumers = vec![];
131133
for (graph_ty, node) in self.tys.iter() {
@@ -137,6 +139,9 @@ impl MoveTypeGraph {
137139
.edges_directed(*node, petgraph::Direction::Outgoing)
138140
{
139141
if let TypeGraphNode::Function(m, f) = &self.graph[edge.target()] {
142+
if public_only && f.visibility != MoveFunctionVisibility::Public {
143+
continue;
144+
}
140145
consumers.push((m, f));
141146
}
142147
}
@@ -148,6 +153,7 @@ impl MoveTypeGraph {
148153
pub fn find_producers(
149154
&self,
150155
ty: &MoveAbiSignatureToken,
156+
public_only: bool,
151157
) -> Vec<(MoveModuleId, MoveFunctionAbi)> {
152158
let mut producers = vec![];
153159
for (graph_ty, node) in self.tys.iter() {
@@ -159,6 +165,9 @@ impl MoveTypeGraph {
159165
.edges_directed(*node, petgraph::Direction::Incoming)
160166
{
161167
if let TypeGraphNode::Function(m, f) = &self.graph[edge.source()] {
168+
if public_only && f.visibility != MoveFunctionVisibility::Public {
169+
continue;
170+
}
162171
producers.push((m.clone(), f.clone()));
163172
}
164173
}

crates/movy-fuzz/src/executor.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,18 @@ where
148148
.expect("tracer should be present when tracing is enabled")
149149
.outcome();
150150

151+
trace!("Execution finished with status: {:?}", effects.status());
152+
151153
let (stage_idx, success) = match effects.status() {
152-
ExecutionStatus::Failure { command, .. } => (command.map(|c| c), false),
154+
ExecutionStatus::Failure { command, .. } => (
155+
// command index may be out of bound when meeting non-aborted error
156+
if command.is_some_and(|c| c < input.sequence().commands.len()) {
157+
command.clone()
158+
} else {
159+
None
160+
},
161+
false,
162+
),
153163
_ => (None, true),
154164
};
155165
if effects.status().is_err() {

crates/movy-fuzz/src/meta.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ fn should_skip_function(base: &Metadata, func_data: &MoveFunctionAbi) -> bool {
216216
MoveAbiSignatureToken::Reference(_) | MoveAbiSignatureToken::MutableReference(_)
217217
);
218218
let hanging_hot_potato =
219-
ret_ty.is_hot_potato() && base.type_graph.find_consumers(ret_ty).is_empty();
219+
ret_ty.is_hot_potato() && base.type_graph.find_consumers(ret_ty, true).is_empty();
220220
if self_used || ret_ref || hanging_hot_potato {
221221
return true;
222222
}

crates/movy-fuzz/src/mutators/object_data.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ impl ObjectData {
184184
// continue; // Skip parameters that have the Copy ability
185185
// }
186186
let instantiated_param = param.subst(ty_args_map).unwrap();
187+
let partial_instantiation = param.partial_subst(ty_args_map);
187188
existing_objects
188189
.get_mut(&instantiated_param)
189190
.unwrap_or_else(|| {
@@ -203,25 +204,26 @@ impl ObjectData {
203204
if matches!(arg, SequenceArgument::Input(_)) {
204205
continue; // Skip input arguments for key store and hot potatoes
205206
}
206-
if param.is_balance() {
207+
if partial_instantiation.is_balance() {
207208
balances.retain(|a| *a != *arg); // Remove from balances if it is a balance object
208209
}
209-
if param.is_key_store() {
210+
if partial_instantiation.is_key_store() {
210211
key_store_objects.retain(|a| *a != *arg); // Remove from key_store_objects if it is a key store object
211212
}
212-
if param.is_hot_potato() {
213+
if partial_instantiation.is_hot_potato() {
213214
hot_potatoes.remove(
214215
hot_potatoes
215216
.iter()
216217
.position(|x| x == &instantiated_param)
217218
.unwrap_or_else(|| {
218219
panic!(
219-
"Expected hot potato object for type {:?}, input {}",
220+
"Expected hot potato object for type {}, input {}, hot potatoes {:?}",
220221
instantiated_param,
221222
MoveFuzzInput {
222223
sequence: ptb.clone(),
223224
..Default::default()
224-
}
225+
},
226+
hot_potatoes
225227
)
226228
}),
227229
);
@@ -265,6 +267,7 @@ impl ObjectData {
265267
continue;
266268
}
267269
let instantiated_ret_ty = ret_ty.subst(ty_args_map).unwrap();
270+
let partial_instantiation = ret_ty.partial_subst(ty_args_map);
268271
if !matches!(instantiated_ret_ty, MoveTypeTag::Struct(_)) {
269272
continue; // Only process struct return types
270273
}
@@ -277,13 +280,13 @@ impl ObjectData {
277280
.entry(instantiated_ret_ty.clone())
278281
.or_default()
279282
.push((res_arg, Gate::Owned));
280-
if ret_ty.is_balance() {
283+
if partial_instantiation.is_balance() {
281284
balances.push(res_arg);
282285
}
283-
if ret_ty.is_key_store() {
286+
if partial_instantiation.is_key_store() {
284287
key_store_objects.push(res_arg);
285288
}
286-
if ret_ty.is_hot_potato() {
289+
if partial_instantiation.is_hot_potato() {
287290
hot_potatoes.push(instantiated_ret_ty);
288291
}
289292
}
@@ -899,7 +902,7 @@ where
899902
.flat_map(|type_tag| {
900903
meta_state
901904
.type_graph
902-
.find_consumers(&MoveAbiSignatureToken::from_type_tag_lossy(type_tag))
905+
.find_consumers(&MoveAbiSignatureToken::from_type_tag_lossy(type_tag), true)
903906
.iter()
904907
.map(|(module_id, consumer_function)| {
905908
FunctionIdent::new(

crates/movy-fuzz/src/mutators/sequence/append.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ where
209209
}
210210
let arg_type = struct_params.remove(0).partial_subst(&ty_args);
211211

212-
let funcs = state.fuzz_state().type_graph.find_producers(&arg_type);
212+
let funcs = state
213+
.fuzz_state()
214+
.type_graph
215+
.find_producers(&arg_type, true);
213216
// except itself
214217
let funcs = funcs
215218
.iter()

crates/movy-fuzz/src/mutators/utils.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ impl StageReplay {
8383
self.reset_progress();
8484
return StageReplayAction::Fresh;
8585
};
86+
debug!(
87+
"StageReplay decide: current stage idx {}, recorded stage idx {:?}, attempts {}",
88+
stage_idx, self.stage_idx, self.attempts
89+
);
8690

8791
let prev_stage = self.stage_idx;
8892
self.stage_idx = match self.stage_idx {
@@ -266,7 +270,7 @@ where
266270
let mut ty_args = if let Some(stage_idx) = stage_idx {
267271
let Some(cmd) = ptb.commands.get_mut(*stage_idx) else {
268272
warn!(
269-
"Stage idx {} out of bounds for commands: {:?}",
273+
"Stage idx {} out of bounds for commands mutating ty args: {:?}",
270274
stage_idx, ptb.commands
271275
);
272276
return MutationResult::Skipped;

crates/movy-replay/src/tracer/concolic.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl ConcolicState {
316316
self.stack.pop();
317317
}
318318
if self.stack.len() != s.value.len() {
319-
debug!(
319+
warn!(
320320
"stack: {:?}, stack from trace: {:?}, event: {:?}, disabling concolic execution",
321321
self.stack, s.value, event
322322
);
@@ -423,6 +423,13 @@ impl ConcolicState {
423423
instruction,
424424
extra,
425425
} => {
426+
trace!(
427+
"Before instruction at pc {}: {:?}, extra: {:?}. Current stack: {:?}",
428+
pc,
429+
instruction,
430+
extra,
431+
stack.map(|s| &s.value)
432+
);
426433
match instruction {
427434
Bytecode::Pop
428435
| Bytecode::BrTrue(_)
@@ -1003,11 +1010,14 @@ impl ConcolicState {
10031010
_ => unreachable!(),
10041011
}
10051012
}
1013+
Bytecode::VariantSwitch(_) => {
1014+
self.stack.pop();
1015+
}
10061016
_ => {}
10071017
}
10081018
}
10091019
_ => {
1010-
trace!("Unsupported event: {:?}", event);
1020+
// trace!("Unsupported event: {:?}", event);
10111021
}
10121022
}
10131023
None

0 commit comments

Comments
 (0)