iota_verifier_latest/
global_storage_access_verifier.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use iota_types::error::ExecutionError;
6use move_binary_format::file_format::{Bytecode, CompiledModule};
7
8use crate::verification_failure;
9
10pub fn verify_module(module: &CompiledModule) -> Result<(), ExecutionError> {
11    verify_global_storage_access(module)
12}
13
14/// Global storage in iota is handled by iota instead of within Move.
15/// Hence we want to forbid any global storage access in Move.
16fn verify_global_storage_access(module: &CompiledModule) -> Result<(), ExecutionError> {
17    for func_def in &module.function_defs {
18        if func_def.code.is_none() {
19            continue;
20        }
21        let code = &func_def.code.as_ref().unwrap().code;
22        let mut invalid_bytecode = vec![];
23        for bytecode in code {
24            match bytecode {
25                Bytecode::MoveFromDeprecated(_)
26                | Bytecode::MoveFromGenericDeprecated(_)
27                | Bytecode::MoveToDeprecated(_)
28                | Bytecode::MoveToGenericDeprecated(_)
29                | Bytecode::ImmBorrowGlobalDeprecated(_)
30                | Bytecode::MutBorrowGlobalDeprecated(_)
31                | Bytecode::ImmBorrowGlobalGenericDeprecated(_)
32                | Bytecode::MutBorrowGlobalGenericDeprecated(_)
33                | Bytecode::ExistsDeprecated(_)
34                | Bytecode::ExistsGenericDeprecated(_) => {
35                    invalid_bytecode.push(bytecode);
36                }
37                Bytecode::Pop
38                | Bytecode::Ret
39                | Bytecode::BrTrue(_)
40                | Bytecode::BrFalse(_)
41                | Bytecode::Branch(_)
42                | Bytecode::LdU8(_)
43                | Bytecode::LdU16(_)
44                | Bytecode::LdU32(_)
45                | Bytecode::LdU64(_)
46                | Bytecode::LdU128(_)
47                | Bytecode::LdU256(_)
48                | Bytecode::CastU8
49                | Bytecode::CastU16
50                | Bytecode::CastU32
51                | Bytecode::CastU64
52                | Bytecode::CastU128
53                | Bytecode::CastU256
54                | Bytecode::LdConst(_)
55                | Bytecode::LdTrue
56                | Bytecode::LdFalse
57                | Bytecode::CopyLoc(_)
58                | Bytecode::MoveLoc(_)
59                | Bytecode::StLoc(_)
60                | Bytecode::Call(_)
61                | Bytecode::CallGeneric(_)
62                | Bytecode::Pack(_)
63                | Bytecode::PackGeneric(_)
64                | Bytecode::Unpack(_)
65                | Bytecode::UnpackGeneric(_)
66                | Bytecode::ReadRef
67                | Bytecode::WriteRef
68                | Bytecode::FreezeRef
69                | Bytecode::MutBorrowLoc(_)
70                | Bytecode::ImmBorrowLoc(_)
71                | Bytecode::MutBorrowField(_)
72                | Bytecode::MutBorrowFieldGeneric(_)
73                | Bytecode::ImmBorrowField(_)
74                | Bytecode::ImmBorrowFieldGeneric(_)
75                | Bytecode::Add
76                | Bytecode::Sub
77                | Bytecode::Mul
78                | Bytecode::Mod
79                | Bytecode::Div
80                | Bytecode::BitOr
81                | Bytecode::BitAnd
82                | Bytecode::Xor
83                | Bytecode::Shl
84                | Bytecode::Shr
85                | Bytecode::Or
86                | Bytecode::And
87                | Bytecode::Not
88                | Bytecode::Eq
89                | Bytecode::Neq
90                | Bytecode::Lt
91                | Bytecode::Gt
92                | Bytecode::Le
93                | Bytecode::Ge
94                | Bytecode::Abort
95                | Bytecode::Nop
96                | Bytecode::VecPack(_, _)
97                | Bytecode::VecLen(_)
98                | Bytecode::VecImmBorrow(_)
99                | Bytecode::VecMutBorrow(_)
100                | Bytecode::VecPushBack(_)
101                | Bytecode::VecPopBack(_)
102                | Bytecode::VecUnpack(_, _)
103                | Bytecode::VecSwap(_)
104                | Bytecode::PackVariant(_)
105                | Bytecode::PackVariantGeneric(_)
106                | Bytecode::UnpackVariant(_)
107                | Bytecode::UnpackVariantImmRef(_)
108                | Bytecode::UnpackVariantMutRef(_)
109                | Bytecode::UnpackVariantGeneric(_)
110                | Bytecode::UnpackVariantGenericImmRef(_)
111                | Bytecode::UnpackVariantGenericMutRef(_)
112                | Bytecode::VariantSwitch(_) => {}
113            }
114        }
115        if !invalid_bytecode.is_empty() {
116            return Err(verification_failure(format!(
117                "Access to Move global storage is not allowed. Found in function {}: {:?}",
118                module.identifier_at(module.function_handle_at(func_def.function).name),
119                invalid_bytecode,
120            )));
121        }
122    }
123    Ok(())
124}