diff --git a/p-token/src/processor/close_account.rs b/p-token/src/processor/close_account.rs index 0fa979bf..d611205f 100644 --- a/p-token/src/processor/close_account.rs +++ b/p-token/src/processor/close_account.rs @@ -37,7 +37,8 @@ pub fn process_close_account(accounts: &[AccountInfo]) -> ProgramResult { .unwrap_or(&source_account.owner); if !source_account.is_owned_by_system_program_or_incinerator() { - validate_owner(authority, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(authority, authority_info, remaining)? }; } else if destination_account_info.key() != &INCINERATOR_ID { return Err(ProgramError::InvalidAccountData); } diff --git a/p-token/src/processor/mod.rs b/p-token/src/processor/mod.rs index 34d29c30..c26262a8 100644 --- a/p-token/src/processor/mod.rs +++ b/p-token/src/processor/mod.rs @@ -86,12 +86,15 @@ fn check_account_owner(account_info: &AccountInfo) -> ProgramResult { /// Validates owner(s) are present. /// -/// Note that `owner_account_info` will be immutable borrowed when it represents +/// +/// # Safety +/// +/// The `owner_account_info` will be immutable borrowed when it represents /// a multisig account, therefore it should not have any mutable borrows when /// calling this function. #[inline(always)] #[allow(clippy::arithmetic_side_effects)] -fn validate_owner( +unsafe fn validate_owner( expected_owner: &Pubkey, owner_account_info: &AccountInfo, signers: &[AccountInfo], diff --git a/p-token/src/processor/revoke.rs b/p-token/src/processor/revoke.rs index cc1b92da..fd97d76e 100644 --- a/p-token/src/processor/revoke.rs +++ b/p-token/src/processor/revoke.rs @@ -28,7 +28,8 @@ pub fn process_revoke(accounts: &[AccountInfo]) -> ProgramResult { return Err(TokenError::AccountFrozen.into()); } - validate_owner(&source_account.owner, owner_info, remaining)?; + // SAFETY: `owner_info` is not currently borrowed. + unsafe { validate_owner(&source_account.owner, owner_info, remaining)? } source_account.clear_delegate(); source_account.set_delegated_amount(0); diff --git a/p-token/src/processor/set_authority.rs b/p-token/src/processor/set_authority.rs index 38e43319..000c1a56 100644 --- a/p-token/src/processor/set_authority.rs +++ b/p-token/src/processor/set_authority.rs @@ -50,7 +50,8 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8]) match authority_type { AuthorityType::AccountOwner => { - validate_owner(&account.owner, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(&account.owner, authority_info, remaining)? }; if let Some(authority) = new_authority { account.owner = *authority; @@ -67,7 +68,8 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8]) } AuthorityType::CloseAccount => { let authority = account.close_authority().unwrap_or(&account.owner); - validate_owner(authority, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(authority, authority_info, remaining)? }; if let Some(authority) = new_authority { account.set_close_authority(authority); @@ -90,7 +92,8 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8]) // mint_authority. let mint_authority = mint.mint_authority().ok_or(TokenError::FixedSupply)?; - validate_owner(mint_authority, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(mint_authority, authority_info, remaining)? }; if let Some(authority) = new_authority { mint.set_mint_authority(authority); @@ -105,7 +108,8 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8]) .freeze_authority() .ok_or(TokenError::MintCannotFreeze)?; - validate_owner(freeze_authority, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(freeze_authority, authority_info, remaining)? }; if let Some(authority) = new_authority { mint.set_freeze_authority(authority); diff --git a/p-token/src/processor/shared/approve.rs b/p-token/src/processor/shared/approve.rs index d2fcaa0c..1f2f68bf 100644 --- a/p-token/src/processor/shared/approve.rs +++ b/p-token/src/processor/shared/approve.rs @@ -69,7 +69,8 @@ pub fn process_approve( } } - validate_owner(&source_account.owner, owner_info, remaining)?; + // SAFETY: `owner_info` is not currently borrowed. + unsafe { validate_owner(&source_account.owner, owner_info, remaining)? }; // Sets the delegate and delegated amount. diff --git a/p-token/src/processor/shared/burn.rs b/p-token/src/processor/shared/burn.rs index f8f7215e..28537c1a 100644 --- a/p-token/src/processor/shared/burn.rs +++ b/p-token/src/processor/shared/burn.rs @@ -54,7 +54,8 @@ pub fn process_burn( if !source_account.is_owned_by_system_program_or_incinerator() { match source_account.delegate() { Some(delegate) if authority_info.key() == delegate => { - validate_owner(delegate, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(delegate, authority_info, remaining)? }; let delegated_amount = source_account .delegated_amount() @@ -67,7 +68,8 @@ pub fn process_burn( } } _ => { - validate_owner(&source_account.owner, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(&source_account.owner, authority_info, remaining)? }; } } } diff --git a/p-token/src/processor/shared/mint_to.rs b/p-token/src/processor/shared/mint_to.rs index 68508025..c4dbe41b 100644 --- a/p-token/src/processor/shared/mint_to.rs +++ b/p-token/src/processor/shared/mint_to.rs @@ -48,7 +48,8 @@ pub fn process_mint_to( } match mint.mint_authority() { - Some(mint_authority) => validate_owner(mint_authority, owner_info, remaining)?, + // SAFETY: `owner_info` is not currently borrowed. + Some(mint_authority) => unsafe { validate_owner(mint_authority, owner_info, remaining)? }, None => return Err(TokenError::FixedSupply.into()), } diff --git a/p-token/src/processor/shared/toggle_account_state.rs b/p-token/src/processor/shared/toggle_account_state.rs index f2a2eef7..8ae3deca 100644 --- a/p-token/src/processor/shared/toggle_account_state.rs +++ b/p-token/src/processor/shared/toggle_account_state.rs @@ -35,7 +35,8 @@ pub fn process_toggle_account_state(accounts: &[AccountInfo], freeze: bool) -> P let mint = unsafe { load::(mint_info.borrow_data_unchecked())? }; match mint.freeze_authority() { - Some(authority) => validate_owner(authority, authority_info, remaining), + // SAFETY: `authority_info` is not currently borrowed. + Some(authority) => unsafe { validate_owner(authority, authority_info, remaining) }, None => Err(TokenError::MintCannotFreeze.into()), }?; diff --git a/p-token/src/processor/shared/transfer.rs b/p-token/src/processor/shared/transfer.rs index 269ab607..3848f7e9 100644 --- a/p-token/src/processor/shared/transfer.rs +++ b/p-token/src/processor/shared/transfer.rs @@ -127,7 +127,8 @@ pub fn process_transfer( // Validates the authority (delegate or owner). if source_account.delegate() == Some(authority_info.key()) { - validate_owner(authority_info.key(), authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(authority_info.key(), authority_info, remaining)? }; let delegated_amount = source_account .delegated_amount() @@ -142,7 +143,8 @@ pub fn process_transfer( } } } else { - validate_owner(&source_account.owner, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(&source_account.owner, authority_info, remaining)? }; } if self_transfer || amount == 0 { diff --git a/p-token/src/processor/withdraw_excess_lamports.rs b/p-token/src/processor/withdraw_excess_lamports.rs index efe49f88..ca326382 100644 --- a/p-token/src/processor/withdraw_excess_lamports.rs +++ b/p-token/src/processor/withdraw_excess_lamports.rs @@ -30,7 +30,8 @@ pub fn process_withdraw_excess_lamports(accounts: &[AccountInfo]) -> ProgramResu return Err(TokenError::NativeNotSupported.into()); } - validate_owner(&account.owner, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(&account.owner, authority_info, remaining)? }; } Mint::LEN => { // SAFETY: `source_data` has the same length as `Mint`. @@ -38,7 +39,8 @@ pub fn process_withdraw_excess_lamports(accounts: &[AccountInfo]) -> ProgramResu match mint.mint_authority() { Some(mint_authority) => { - validate_owner(mint_authority, authority_info, remaining)?; + // SAFETY: `authority_info` is not currently borrowed. + unsafe { validate_owner(mint_authority, authority_info, remaining)? }; } None if source_account_info == authority_info => { // Comparing whether the AccountInfo's "point" to the same account or @@ -58,7 +60,8 @@ pub fn process_withdraw_excess_lamports(accounts: &[AccountInfo]) -> ProgramResu } } Multisig::LEN => { - validate_owner(source_account_info.key(), authority_info, remaining)?; + // SAFETY: `authority_info` is not currently mutably borrowed. + unsafe { validate_owner(source_account_info.key(), authority_info, remaining)? }; } _ => return Err(TokenError::InvalidState.into()), }