diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.exp new file mode 100644 index 0000000000000..e3a089eb95925 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-25: +Error: Failed to verify the Move module, reason: "ID leak detected in function foo: ID leaked through function call.". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.mvir new file mode 100644 index 0000000000000..01afb472b8f99 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/direct_leak_through_call.mvir @@ -0,0 +1,25 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + transfer(id: ID.VersionedID) { + label l0: + abort 0; + } + + foo(f: Self.Foo, v: &mut vector) { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + Self.transfer(move(id)); + return; + } + +} diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.exp new file mode 100644 index 0000000000000..e3a089eb95925 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-25: +Error: Failed to verify the Move module, reason: "ID leak detected in function foo: ID leaked through function call.". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.mvir new file mode 100644 index 0000000000000..0e0b42163890c --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/indirect_leak_through_call.mvir @@ -0,0 +1,25 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + transfer(id: Self.Foo) { + label l0: + abort 0; + } + + foo(f: Self.Foo, v: &mut vector) { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + Self.transfer(Foo { id: move(id) }); + return; + } + +} diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.exp new file mode 100644 index 0000000000000..75cef76189499 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-19: +Error: Failed to verify the Move module, reason: "ID leak detected in function foo: ID leaked through function return.". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.mvir new file mode 100644 index 0000000000000..aa46b29268188 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_direct_return.mvir @@ -0,0 +1,19 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + foo(f: Self.Foo): ID.VersionedID { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + return move(id); + } + +} diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.exp new file mode 100644 index 0000000000000..75cef76189499 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-19: +Error: Failed to verify the Move module, reason: "ID leak detected in function foo: ID leaked through function return.". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.mvir new file mode 100644 index 0000000000000..1495ca718bfdb --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_indirect_return.mvir @@ -0,0 +1,19 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + foo(f: Self.Foo): Self.Foo { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + return Foo { id: move(id) }; + } + +} diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.exp new file mode 100644 index 0000000000000..dd958c3275c62 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-20: +Error: Failed to publish the Move module(s), reason: "VMError with status WRITEREF_WITHOUT_DROP_ABILITY at location Module ModuleId { address: _, name: Identifier(\"M\") } at index 0 for function definition at code offset 5 in function definition 0". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.mvir new file mode 100644 index 0000000000000..619d941058c35 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_reference.mvir @@ -0,0 +1,20 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + foo(f: Self.Foo, ref: &mut ID.VersionedID) { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + *move(ref) = move(id); + return; + } + +} diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.exp b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.exp new file mode 100644 index 0000000000000..23c7c42090cb6 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 4-20: +Error: Failed to verify the Move module, reason: "ID leak detected in function foo: ID is leaked into a vector". diff --git a/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.mvir b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.mvir new file mode 100644 index 0000000000000..006197d629d85 --- /dev/null +++ b/crates/sui-verifier-transactional-tests/transactional-tests/tests/id_leak/through_vector.mvir @@ -0,0 +1,20 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.M { + import 0x2.ID; + + struct Foo has key { + id: ID.VersionedID, + } + + foo(f: Self.Foo, v: &mut vector) { + let id: ID.VersionedID; + label l0: + Foo { id } = move(f); + vec_push_back(move(v), move(id)); + return; + } + +} diff --git a/crates/sui-verifier/tests/id_leak_verification_test.rs b/crates/sui-verifier/tests/id_leak_verification_test.rs deleted file mode 100644 index cd5241604c54c..0000000000000 --- a/crates/sui-verifier/tests/id_leak_verification_test.rs +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2021, Facebook, Inc. and its affiliates -// Copyright (c) 2022, Mysten Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -mod common; - -pub use common::module_builder::*; -use move_binary_format::file_format::*; -use sui_verifier::id_leak_verifier::verify_module; - -fn make_module_with_default_struct() -> (ModuleBuilder, StructInfo, StructInfo) { - /* - Creating a module with a default struct Foo: - - struct Foo has key { - id: SUI_FRAMEWORK_ADDRESS::ID::VersionedID - } - */ - let (mut module, id_struct) = ModuleBuilder::default(); - let foo_struct = module.add_struct( - module.get_self_index(), - "Foo", - AbilitySet::EMPTY | Ability::Key, - vec![("id", SignatureToken::Struct(id_struct.handle))], - ); - (module, id_struct, foo_struct) -} - -#[test] -fn id_leak_through_direct_return() { - /* - fun foo(f: Foo): 0x1::ID::VersionedID { - let Foo { id: id } = f; - return id; - } - */ - let (mut module, id_struct, foo_struct) = make_module_with_default_struct(); - let func = module.add_function( - module.get_self_index(), - "foo", - vec![SignatureToken::Struct(foo_struct.handle)], - vec![SignatureToken::Struct(id_struct.handle)], - ); - module.set_bytecode( - func.def, - vec![ - Bytecode::MoveLoc(0), - Bytecode::Unpack(foo_struct.def), - Bytecode::Ret, - ], - ); - let result = verify_module(module.get_module()); - assert!(result - .unwrap_err() - .to_string() - .contains("ID leak detected in function foo: ID leaked through function return.")); -} - -#[test] -fn id_leak_through_indirect_return() { - /* - fun foo(f: Foo): Foo { - let Foo { id: id } = f; - let r = Foo { id: id }; - return r; - } - */ - let (mut module, _, foo_struct) = make_module_with_default_struct(); - let func = module.add_function( - module.get_self_index(), - "foo", - vec![SignatureToken::Struct(foo_struct.handle)], - vec![SignatureToken::Struct(foo_struct.handle)], - ); - module.set_bytecode( - func.def, - vec![ - Bytecode::MoveLoc(0), - Bytecode::Unpack(foo_struct.def), - Bytecode::Pack(foo_struct.def), - Bytecode::Ret, - ], - ); - let result = verify_module(module.get_module()); - assert!(result - .unwrap_err() - .to_string() - .contains("ID leak detected in function foo: ID leaked through function return.")); -} - -#[test] -fn id_leak_through_reference() { - /* - fun foo(f: Foo, ref: &mut 0x1::ID::VersionedID) { - let Foo { id: id } = f; - *ref = id; - } - */ - let (mut module, id_struct, foo_struct) = make_module_with_default_struct(); - let func = module.add_function( - module.get_self_index(), - "foo", - vec![ - SignatureToken::Struct(foo_struct.handle), - SignatureToken::MutableReference(Box::new(SignatureToken::Struct(id_struct.handle))), - ], - vec![], - ); - module.set_bytecode( - func.def, - vec![ - Bytecode::MoveLoc(0), - Bytecode::Unpack(foo_struct.def), - Bytecode::MoveLoc(1), - Bytecode::WriteRef, - Bytecode::Ret, - ], - ); - let result = verify_module(module.get_module()); - assert!(result - .unwrap_err() - .to_string() - .contains("ID leak detected in function foo: ID is leaked to a reference.")); -} - -#[test] -fn id_direct_leak_through_call() { - /* - fun transfer(id: 0x1::ID::VersionedID); - - fun foo(f: Foo) { - let Foo { id: id } = f; - transfer(id); - } - */ - let (mut module, id_struct, foo_struct) = make_module_with_default_struct(); - let transfer_func = module.add_function( - module.get_self_index(), - "transfer", - vec![SignatureToken::Struct(id_struct.handle)], - vec![], - ); - let foo_func = module.add_function( - module.get_self_index(), - "foo", - vec![SignatureToken::Struct(foo_struct.handle)], - vec![], - ); - module.set_bytecode( - foo_func.def, - vec![ - Bytecode::MoveLoc(0), - Bytecode::Unpack(foo_struct.def), - Bytecode::Call(transfer_func.handle), - ], - ); - let result = verify_module(module.get_module()); - assert!(result - .unwrap_err() - .to_string() - .contains("ID leak detected in function foo: ID leaked through function call.")); -} - -#[test] -fn id_indirect_leak_through_call() { - /* - fun transfer(f: Foo); - - fun foo(f: Foo) { - let Foo { id: id } = f; - let newf = Foo { id: id }; - transfer(newf); - } - */ - let (mut module, id_struct, foo_struct) = make_module_with_default_struct(); - let transfer_func = module.add_function( - module.get_self_index(), - "transfer", - vec![SignatureToken::Struct(id_struct.handle)], - vec![], - ); - let foo_func = module.add_function( - module.get_self_index(), - "foo", - vec![SignatureToken::Struct(foo_struct.handle)], - vec![], - ); - module.set_bytecode( - foo_func.def, - vec![ - Bytecode::MoveLoc(0), - Bytecode::Unpack(foo_struct.def), - Bytecode::Pack(foo_struct.def), - Bytecode::Call(transfer_func.handle), - ], - ); - let result = verify_module(module.get_module()); - assert!(result - .unwrap_err() - .to_string() - .contains("ID leak detected in function foo: ID leaked through function call.")); -}