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

Commit

Permalink
[verifier] add version-gating to type instantiation check
Browse files Browse the repository at this point in the history
78a9e2b was known to be a breaking change, but it was unclear whether it would break real code. Turns out that it does, so preserve the old behavior in older bytecode versions
  • Loading branch information
sblackshear committed Dec 20, 2022
1 parent 92404f3 commit 871df22
Showing 1 changed file with 43 additions and 29 deletions.
72 changes: 43 additions & 29 deletions language/move-bytecode-verifier/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use move_binary_format::{
FunctionHandle, Signature, SignatureIndex, SignatureToken, StructDefinition,
StructFieldInformation, StructTypeParameter, TableIndex,
},
file_format_common::VERSION_6,
IndexKind,
};
use move_core_types::vm_status::StatusCode;
Expand Down Expand Up @@ -320,37 +321,50 @@ impl<'a> SignatureChecker<'a> {
s: &SignatureToken,
type_parameters: &[AbilitySet],
) -> PartialVMResult<()> {
for ty in s.preorder_traversal() {
match ty {
SignatureToken::StructInstantiation(idx, type_arguments) => {
// Check that the instantiation satisfies the `idx` struct's constraints
// Cannot be checked completely if we do not know the constraints of type parameters
// i.e. it cannot be checked unless we are inside some module member. The only case
// where that happens is when checking the signature pool itself
let sh = self.resolver.struct_handle_at(*idx);
self.check_generic_instance(
type_arguments,
sh.type_param_constraints(),
type_parameters,
)?
}
SignatureToken::Reference(_)
| SignatureToken::MutableReference(_)
| SignatureToken::Vector(_)
| SignatureToken::TypeParameter(_)
| SignatureToken::Struct(_)
| SignatureToken::Bool
| SignatureToken::U8
| SignatureToken::U16
| SignatureToken::U32
| SignatureToken::U64
| SignatureToken::U128
| SignatureToken::U256
| SignatureToken::Address
| SignatureToken::Signer => (),
if self.resolver.version() >= VERSION_6 {
for ty in s.preorder_traversal() {
self.check_type_instantiation_(ty, type_parameters)?
}
Ok(())
} else {
// preserve buggy, but harmless old behavior for backward compatibility
self.check_type_instantiation_(s, type_parameters)
}
}

fn check_type_instantiation_(
&self,
s: &SignatureToken,
type_parameters: &[AbilitySet],
) -> PartialVMResult<()> {
match s {
SignatureToken::StructInstantiation(idx, type_arguments) => {
// Check that the instantiation satisfies the `idx` struct's constraints
// Cannot be checked completely if we do not know the constraints of type parameters
// i.e. it cannot be checked unless we are inside some module member. The only case
// where that happens is when checking the signature pool itself
let sh = self.resolver.struct_handle_at(*idx);
self.check_generic_instance(
type_arguments,
sh.type_param_constraints(),
type_parameters,
)
}
SignatureToken::Reference(_)
| SignatureToken::MutableReference(_)
| SignatureToken::Vector(_)
| SignatureToken::TypeParameter(_)
| SignatureToken::Struct(_)
| SignatureToken::Bool
| SignatureToken::U8
| SignatureToken::U16
| SignatureToken::U32
| SignatureToken::U64
| SignatureToken::U128
| SignatureToken::U256
| SignatureToken::Address
| SignatureToken::Signer => Ok(()),
}
Ok(())
}

// Checks if the given types are well defined and satisfy the constraints in the given context.
Expand Down

0 comments on commit 871df22

Please sign in to comment.