Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
[bytecode verifier] Meter type instantiations (#64)
Browse files Browse the repository at this point in the history
Instead of just metering size of types on the operand stack, also meter size of type instantiations in calls and other places. This e.g. capture the size of types in calls like `f<T>()`, where the type does not appear on the operand stack.
  • Loading branch information
wrwg committed Mar 1, 2023
1 parent abfa8d4 commit 8c10fb0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This testsuite can be run in a specific way to print the time until a 'complex' program is detected or accepted. Call as in:

```
cargo test --release --features=address32 -- --nocapture 1>/dev/null
```
7 changes: 4 additions & 3 deletions language/move-bytecode-verifier/src/absint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::meter::Meter;
use move_binary_format::{
binary_views::FunctionView,
control_flow_graph::{BlockId, ControlFlowGraph},
errors::PartialVMResult,
file_format::{Bytecode, CodeOffset},
};
use std::collections::BTreeMap;
Expand Down Expand Up @@ -56,7 +57,7 @@ pub trait TransferFunctions {
index: CodeOffset,
last_index: CodeOffset,
meter: &mut impl Meter,
) -> Result<(), Self::Error>;
) -> PartialVMResult<()>;
}

pub trait AbstractInterpreter: TransferFunctions {
Expand All @@ -66,7 +67,7 @@ pub trait AbstractInterpreter: TransferFunctions {
initial_state: Self::State,
function_view: &FunctionView,
meter: &mut impl Meter,
) -> Result<(), Self::Error> {
) -> PartialVMResult<()> {
let mut inv_map = InvariantMap::new();
let entry_block_id = function_view.cfg().entry_block_id();
let mut next_block = Some(entry_block_id);
Expand Down Expand Up @@ -137,7 +138,7 @@ pub trait AbstractInterpreter: TransferFunctions {
pre_state: &Self::State,
function_view: &FunctionView,
meter: &mut impl Meter,
) -> Result<Self::State, Self::Error> {
) -> PartialVMResult<Self::State> {
let mut state_acc = pre_state.clone();
let block_end = function_view.cfg().block_end(block_id);
for offset in function_view.cfg().instr_indexes(block_id) {
Expand Down
29 changes: 27 additions & 2 deletions language/move-bytecode-verifier/src/type_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,27 @@ impl<'a> TypeSafetyChecker<'a> {
}

fn push(&mut self, meter: &mut impl Meter, ty: SignatureToken) -> PartialVMResult<()> {
self.charge_ty(meter, &ty)?;
self.stack.push(ty);
Ok(())
}

fn charge_ty(&mut self, meter: &mut impl Meter, ty: &SignatureToken) -> PartialVMResult<()> {
meter.add_items(
Scope::Function,
TYPE_NODE_COST,
ty.preorder_traversal().count(),
)?;
self.stack.push(ty);
)
}

fn charge_tys(
&mut self,
meter: &mut impl Meter,
tys: &[SignatureToken],
) -> PartialVMResult<()> {
for ty in tys {
self.charge_ty(meter, ty)?
}
Ok(())
}
}
Expand Down Expand Up @@ -481,6 +496,7 @@ fn verify_instr(
.resolver
.field_instantiation_at(*field_inst_index)?;
let type_inst = verifier.resolver.signature_at(field_inst.type_parameters);
verifier.charge_tys(meter, &type_inst.0)?;
borrow_field(verifier, meter, offset, true, field_inst.handle, type_inst)?
}

Expand All @@ -498,6 +514,7 @@ fn verify_instr(
.resolver
.field_instantiation_at(*field_inst_index)?;
let type_inst = verifier.resolver.signature_at(field_inst.type_parameters);
verifier.charge_tys(meter, &type_inst.0)?;
borrow_field(verifier, meter, offset, false, field_inst.handle, type_inst)?
}

Expand Down Expand Up @@ -564,6 +581,7 @@ fn verify_instr(
let func_inst = verifier.resolver.function_instantiation_at(*idx);
let func_handle = verifier.resolver.function_handle_at(func_inst.handle);
let type_args = &verifier.resolver.signature_at(func_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
call(verifier, meter, offset, func_handle, type_args)?
}

Expand All @@ -582,6 +600,7 @@ fn verify_instr(
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let struct_def = verifier.resolver.struct_def_at(struct_inst.def)?;
let type_args = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
pack(verifier, meter, offset, struct_def, type_args)?
}

Expand All @@ -600,6 +619,7 @@ fn verify_instr(
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let struct_def = verifier.resolver.struct_def_at(struct_inst.def)?;
let type_args = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
unpack(verifier, meter, offset, struct_def, type_args)?
}

Expand Down Expand Up @@ -733,6 +753,7 @@ fn verify_instr(
Bytecode::MutBorrowGlobalGeneric(idx) => {
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let type_inst = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_inst.0)?;
borrow_global(verifier, meter, offset, true, struct_inst.def, type_inst)?
}

Expand All @@ -743,6 +764,7 @@ fn verify_instr(
Bytecode::ImmBorrowGlobalGeneric(idx) => {
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let type_inst = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_inst.0)?;
borrow_global(verifier, meter, offset, false, struct_inst.def, type_inst)?
}

Expand All @@ -755,6 +777,7 @@ fn verify_instr(
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let struct_def = verifier.resolver.struct_def_at(struct_inst.def)?;
let type_args = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
exists(verifier, meter, offset, struct_def, type_args)?
}

Expand All @@ -767,6 +790,7 @@ fn verify_instr(
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let struct_def = verifier.resolver.struct_def_at(struct_inst.def)?;
let type_args = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
move_from(verifier, meter, offset, struct_def, type_args)?
}

Expand All @@ -779,6 +803,7 @@ fn verify_instr(
let struct_inst = verifier.resolver.struct_instantiation_at(*idx)?;
let struct_def = verifier.resolver.struct_def_at(struct_inst.def)?;
let type_args = verifier.resolver.signature_at(struct_inst.type_parameters);
verifier.charge_tys(meter, &type_args.0)?;
move_to(verifier, offset, struct_def, type_args)?
}

Expand Down

0 comments on commit 8c10fb0

Please sign in to comment.