Skip to content

Commit

Permalink
[AptosVM] Remove unwrap in respawned session (aptos-labs#11001)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgemitenkov authored Nov 27, 2023
1 parent f74939a commit 6faef40
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
32 changes: 18 additions & 14 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,13 +836,15 @@ impl AptosVM {
txn_data,
)?;
respawned_session.execute(|session| {
session.execute_function_bypass_visibility(
&MULTISIG_ACCOUNT_MODULE,
SUCCESSFUL_TRANSACTION_EXECUTION_CLEANUP,
vec![],
cleanup_args,
&mut UnmeteredGasMeter,
)
session
.execute_function_bypass_visibility(
&MULTISIG_ACCOUNT_MODULE,
SUCCESSFUL_TRANSACTION_EXECUTION_CLEANUP,
vec![],
cleanup_args,
&mut UnmeteredGasMeter,
)
.map_err(|e| e.into_vm_status())
})?;
Ok(respawned_session)
}
Expand Down Expand Up @@ -873,13 +875,15 @@ impl AptosVM {
.finish(Location::Undefined)
})?);
respawned_session.execute(|session| {
session.execute_function_bypass_visibility(
&MULTISIG_ACCOUNT_MODULE,
FAILED_TRANSACTION_EXECUTION_CLEANUP,
vec![],
cleanup_args,
&mut UnmeteredGasMeter,
)
session
.execute_function_bypass_visibility(
&MULTISIG_ACCOUNT_MODULE,
FAILED_TRANSACTION_EXECUTION_CLEANUP,
vec![],
cleanup_args,
&mut UnmeteredGasMeter,
)
.map_err(|e| e.into_vm_status())
})?;
Ok(respawned_session)
}
Expand Down
27 changes: 23 additions & 4 deletions aptos-move/aptos-vm/src/move_vm_ext/respawned_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ use std::{
sync::Arc,
};

fn unwrap_or_invariant_violation<T>(value: Option<T>, msg: &str) -> Result<T, VMStatus> {
value
.ok_or_else(|| VMStatus::error(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR, err_msg(msg)))
}

/// We finish the session after the user transaction is done running to get the change set and
/// charge gas and storage fee based on it before running storage refunds and the transaction
/// epilogue. The latter needs to see the state view as if the change set is applied on top of
Expand Down Expand Up @@ -83,16 +88,30 @@ impl<'r, 'l> RespawnedSession<'r, 'l> {
.build())
}

pub fn execute<R>(&mut self, fun: impl FnOnce(&mut SessionExt) -> R) -> R {
self.with_session_mut(|session| fun(session.as_mut().unwrap()))
pub fn execute<T>(
&mut self,
fun: impl FnOnce(&mut SessionExt) -> Result<T, VMStatus>,
) -> Result<T, VMStatus> {
self.with_session_mut(|session| {
fun(unwrap_or_invariant_violation(
session.as_mut(),
"VM respawned session has to be set for execution.",
)?)
})
}

pub fn finish(
mut self,
change_set_configs: &ChangeSetConfigs,
) -> Result<VMChangeSet, VMStatus> {
let additional_change_set =
self.with_session_mut(|session| session.take().unwrap().finish(change_set_configs))?;
let additional_change_set = self.with_session_mut(|session| {
unwrap_or_invariant_violation(
session.take(),
"VM session cannot be finished more than once.",
)?
.finish(change_set_configs)
.map_err(|e| e.into_vm_status())
})?;
if additional_change_set.has_creation() {
// After respawning, for example, in the epilogue, there shouldn't be new slots
// created, otherwise there's a potential vulnerability like this:
Expand Down

0 comments on commit 6faef40

Please sign in to comment.