Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
use PROGRAM_OWNER to check executable on account
Browse files Browse the repository at this point in the history
  • Loading branch information
HaoranYi committed Nov 21, 2023
1 parent f2878c0 commit 3a6cae5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 23 deletions.
44 changes: 22 additions & 22 deletions runtime/src/accounts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use {
loaded_programs::LoadedProgramsForTxBatch,
},
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
account::{
is_builtin, is_builtin_or_executable, is_executable, Account, AccountSharedData,
ReadableAccount, WritableAccount,
},
account_utils::StateMut,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
feature_set::{
Expand Down Expand Up @@ -288,25 +291,23 @@ fn load_transaction_accounts(
return Err(TransactionError::InvalidWritableAccount);
}

if account.executable() {
// The upgradeable loader requires the derived ProgramData account
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.state()
// The upgradeable loader requires the derived ProgramData account
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.state()
{
if accounts_db
.load_with_fixed_root(ancestors, &programdata_address)
.is_none()
{
if accounts_db
.load_with_fixed_root(ancestors, &programdata_address)
.is_none()
{
error_counters.account_not_found += 1;
return Err(TransactionError::ProgramAccountNotFound);
}
} else {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
error_counters.account_not_found += 1;
return Err(TransactionError::ProgramAccountNotFound);
}
} else {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
}
} else if account.executable() && message.is_writable(i) {
} else if is_builtin_or_executable(&account) && message.is_writable(i) {
error_counters.invalid_writable_account += 1;
return Err(TransactionError::InvalidWritableAccount);
}
Expand Down Expand Up @@ -355,15 +356,16 @@ fn load_transaction_accounts(
let (program_id, program_account) = accounts
.get(program_index)
.ok_or(TransactionError::ProgramAccountNotFound)?;
let account_found = accounts_found.get(program_index).unwrap_or(&true);
if native_loader::check_id(program_id) {
return Ok(account_indices);
}

let account_found = accounts_found.get(program_index).unwrap_or(&true);
if !account_found {
error_counters.account_not_found += 1;
return Err(TransactionError::ProgramAccountNotFound);
}
if !program_account.executable() {
if !is_builtin_or_executable(program_account) {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
}
Expand All @@ -384,9 +386,7 @@ fn load_transaction_accounts(
if let Some((owner_account, _)) =
accounts_db.load_with_fixed_root(ancestors, owner_id)
{
if !native_loader::check_id(owner_account.owner())
|| !owner_account.executable()
{
if !is_builtin(&owner_account) || !is_executable(&owner_account) {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
}
Expand Down
15 changes: 14 additions & 1 deletion sdk/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use {
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
clock::{Epoch, INITIAL_RENT_EPOCH},
lamports::LamportsError,
loader_v4,
loader_v4, native_loader,
pubkey::Pubkey,
},
serde::{
Expand Down Expand Up @@ -764,6 +764,19 @@ pub const PROGRAM_OWNERS: &[Pubkey] = &[
loader_v4::id(),
];

/// Check if user program is executable.
pub fn is_executable(account: &AccountSharedData) -> bool {
PROGRAM_OWNERS.iter().any(|v| account.owner() == v)
}

pub fn is_builtin(account: &AccountSharedData) -> bool {
native_loader::check_id(account.owner())
}

pub fn is_builtin_or_executable(account: &AccountSharedData) -> bool {
is_builtin(account) || is_executable(account)
}

#[cfg(test)]
pub mod tests {
use super::*;
Expand Down

0 comments on commit 3a6cae5

Please sign in to comment.