14
14
//! 4. Passed to a function cal::;
15
15
use move_binary_format:: {
16
16
binary_views:: { BinaryIndexedView , FunctionView } ,
17
- errors:: { Location , PartialVMError , PartialVMResult } ,
17
+ errors:: PartialVMError ,
18
18
file_format:: {
19
19
Bytecode , CodeOffset , CompiledModule , FunctionDefinitionIndex , FunctionHandle , LocalIndex ,
20
20
StructDefinition , StructFieldInformation ,
@@ -23,9 +23,13 @@ use move_binary_format::{
23
23
use move_bytecode_verifier:: absint:: {
24
24
AbstractDomain , AbstractInterpreter , JoinResult , TransferFunctions ,
25
25
} ;
26
- use move_core_types:: vm_status:: StatusCode ;
27
26
use std:: collections:: BTreeMap ;
28
- use sui_types:: { error:: ExecutionError , id:: OBJECT_MODULE_NAME , SUI_FRAMEWORK_ADDRESS } ;
27
+ use sui_types:: {
28
+ error:: ExecutionError , id:: OBJECT_MODULE_NAME , messages:: ExecutionFailureStatus ,
29
+ SUI_FRAMEWORK_ADDRESS ,
30
+ } ;
31
+
32
+ use crate :: verification_failure;
29
33
30
34
#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
31
35
enum AbstractValue {
@@ -59,9 +63,7 @@ fn verify_id_leak(module: &CompiledModule) -> Result<(), ExecutionError> {
59
63
FunctionView :: function ( module, FunctionDefinitionIndex ( index as u16 ) , code, handle) ;
60
64
let initial_state = AbstractState :: new ( & func_view) ;
61
65
let mut verifier = IDLeakAnalysis :: new ( & binary_view, & func_view) ;
62
- verifier
63
- . analyze_function ( initial_state, & func_view)
64
- . map_err ( |e| e. finish ( Location :: Module ( module. self_id ( ) ) ) ) ?;
66
+ verifier. analyze_function ( initial_state, & func_view) ?;
65
67
}
66
68
67
69
Ok ( ( ) )
@@ -123,7 +125,7 @@ impl<'a> IDLeakAnalysis<'a> {
123
125
}
124
126
125
127
impl < ' a > TransferFunctions for IDLeakAnalysis < ' a > {
126
- type Error = PartialVMError ;
128
+ type Error = ExecutionError ;
127
129
type State = AbstractState ;
128
130
129
131
fn execute (
@@ -132,7 +134,7 @@ impl<'a> TransferFunctions for IDLeakAnalysis<'a> {
132
134
bytecode : & Bytecode ,
133
135
index : CodeOffset ,
134
136
last_index : CodeOffset ,
135
- ) -> PartialVMResult < ( ) > {
137
+ ) -> Result < ( ) , ExecutionError > {
136
138
execute_inner ( self , state, bytecode, index) ?;
137
139
// invariant: the stack should be empty at the end of the block
138
140
// If it is not, something is wrong with the implementation, so throw an invariant
@@ -142,8 +144,8 @@ impl<'a> TransferFunctions for IDLeakAnalysis<'a> {
142
144
false ,
143
145
"Invalid stack transitions. Non-zero stack size at the end of the block" ,
144
146
) ;
145
- return Err ( PartialVMError :: new (
146
- StatusCode :: UNKNOWN_INVARIANT_VIOLATION_ERROR ,
147
+ return Err ( ExecutionError :: from_kind (
148
+ ExecutionFailureStatus :: InvariantViolation ,
147
149
) ) ;
148
150
}
149
151
Ok ( ( ) )
@@ -179,14 +181,19 @@ fn is_call_safe_to_leak(verifier: &IDLeakAnalysis, function_handle: &FunctionHan
179
181
== "delete_child_object" )
180
182
}
181
183
182
- fn call ( verifier : & mut IDLeakAnalysis , function_handle : & FunctionHandle ) -> PartialVMResult < ( ) > {
184
+ fn call (
185
+ verifier : & mut IDLeakAnalysis ,
186
+ function_handle : & FunctionHandle ,
187
+ ) -> Result < ( ) , ExecutionError > {
183
188
let guaranteed_safe = is_call_safe_to_leak ( verifier, function_handle) ;
184
189
let parameters = verifier
185
190
. binary_view
186
191
. signature_at ( function_handle. parameters ) ;
187
192
for _ in 0 ..parameters. len ( ) {
188
193
if verifier. stack . pop ( ) . unwrap ( ) == AbstractValue :: ID && !guaranteed_safe {
189
- return Err ( move_verification_error ( "ID leaked through function call." ) ) ;
194
+ return Err ( verification_failure (
195
+ "ID leaked through function call." . to_string ( ) ,
196
+ ) ) ;
190
197
}
191
198
}
192
199
@@ -204,11 +211,16 @@ fn num_fields(struct_def: &StructDefinition) -> usize {
204
211
}
205
212
}
206
213
207
- fn pack ( verifier : & mut IDLeakAnalysis , struct_def : & StructDefinition ) -> PartialVMResult < ( ) > {
214
+ fn pack (
215
+ verifier : & mut IDLeakAnalysis ,
216
+ struct_def : & StructDefinition ,
217
+ ) -> Result < ( ) , ExecutionError > {
208
218
for _ in 0 ..num_fields ( struct_def) {
209
219
let value = verifier. stack . pop ( ) . unwrap ( ) ;
210
220
if value == AbstractValue :: ID {
211
- return Err ( move_verification_error ( "ID is leaked into a struct." ) ) ;
221
+ return Err ( verification_failure (
222
+ "ID is leaked into a struct." . to_string ( ) ,
223
+ ) ) ;
212
224
}
213
225
}
214
226
verifier. stack . push ( AbstractValue :: NonID ) ;
@@ -239,7 +251,7 @@ fn execute_inner(
239
251
state : & mut AbstractState ,
240
252
bytecode : & Bytecode ,
241
253
_: CodeOffset ,
242
- ) -> PartialVMResult < ( ) > {
254
+ ) -> Result < ( ) , ExecutionError > {
243
255
// TODO: Better diagnostics with location
244
256
match bytecode {
245
257
Bytecode :: Pop => {
@@ -309,7 +321,7 @@ fn execute_inner(
309
321
// Top of stack is the reference, and the second element is the value.
310
322
verifier. stack . pop ( ) . unwrap ( ) ;
311
323
if verifier. stack . pop ( ) . unwrap ( ) == AbstractValue :: ID {
312
- return Err ( move_verification_error ( "ID is leaked to a reference." ) ) ;
324
+ return Err ( verification_failure ( "ID is leaked to a reference." . to_string ( ) ) ) ;
313
325
}
314
326
}
315
327
@@ -353,7 +365,7 @@ fn execute_inner(
353
365
Bytecode :: Ret => {
354
366
for _ in 0 ..verifier. function_view . return_ ( ) . len ( ) {
355
367
if verifier. stack . pop ( ) . unwrap ( ) == AbstractValue :: ID {
356
- return Err ( move_verification_error ( "ID leaked through function return." ) ) ;
368
+ return Err ( verification_failure ( "ID leaked through function return." . to_string ( ) ) ) ;
357
369
}
358
370
}
359
371
}
@@ -389,15 +401,15 @@ fn execute_inner(
389
401
Bytecode :: VecPack ( _, num) => {
390
402
for _ in 0 ..* num {
391
403
if verifier. stack . pop ( ) . unwrap ( ) == AbstractValue :: ID {
392
- return Err ( move_verification_error ( "ID is leaked into a vector" ) ) ;
404
+ return Err ( verification_failure ( "ID is leaked into a vector." . to_string ( ) ) ) ;
393
405
}
394
406
}
395
407
verifier. stack . push ( AbstractValue :: NonID ) ;
396
408
}
397
409
398
410
Bytecode :: VecPushBack ( _) => {
399
411
if verifier. stack . pop ( ) . unwrap ( ) == AbstractValue :: ID {
400
- return Err ( move_verification_error ( "ID is leaked into a vector" ) ) ;
412
+ return Err ( verification_failure ( "ID is leaked into a vector." . to_string ( ) ) ) ;
401
413
}
402
414
verifier. stack . pop ( ) . unwrap ( ) ;
403
415
}
@@ -419,7 +431,7 @@ fn execute_inner(
419
431
Ok ( ( ) )
420
432
}
421
433
422
- fn expect_ok < T > ( res : Result < T , PartialVMError > ) -> PartialVMResult < T > {
434
+ fn expect_ok < T > ( res : Result < T , PartialVMError > ) -> Result < T , ExecutionError > {
423
435
match res {
424
436
Ok ( x) => Ok ( x) ,
425
437
Err ( partial_vm_error) => {
@@ -429,15 +441,9 @@ fn expect_ok<T>(res: Result<T, PartialVMError>) -> PartialVMResult<T> {
429
441
Got error: {partial_vm_error:?}"
430
442
) ;
431
443
// This is an internal error, but we cannot accept the module as safe
432
- Err ( PartialVMError :: new (
433
- StatusCode :: UNKNOWN_INVARIANT_VIOLATION_ERROR ,
444
+ Err ( ExecutionError :: from_kind (
445
+ ExecutionFailureStatus :: InvariantViolation ,
434
446
) )
435
447
}
436
448
}
437
449
}
438
-
439
- #[ must_use]
440
- fn move_verification_error ( msg : impl std:: fmt:: Display ) -> PartialVMError {
441
- PartialVMError :: new ( StatusCode :: UNKNOWN_VERIFICATION_ERROR )
442
- . with_message ( format ! ( "Sui Move Bytecode Verification Error: {}" , msg) )
443
- }
0 commit comments