Skip to content

Commit

Permalink
don't load executable accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
seanyoung committed Mar 21, 2024
1 parent 1e08e90 commit 45a967b
Show file tree
Hide file tree
Showing 10 changed files with 718 additions and 109 deletions.
3 changes: 3 additions & 0 deletions ledger-tool/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use {
account_utils::StateMut,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
pubkey::Pubkey,
rent_collector::RENT_EXEMPT_RENT_EPOCH,
slot_history::Slot,
transaction_context::{IndexOfAccount, InstructionAccount},
},
Expand Down Expand Up @@ -337,6 +338,8 @@ fn load_program<'a>(
&contents,
&loader_key,
account_size,
RENT_EXEMPT_RENT_EPOCH,
1,
slot,
Arc::new(program_runtime_environment),
false,
Expand Down
44 changes: 43 additions & 1 deletion program-runtime/src/loaded_programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use {
clock::{Epoch, Slot},
loader_v4,
pubkey::Pubkey,
rent_collector::RENT_EXEMPT_RENT_EPOCH,
saturating_add_assign,
},
std::{
Expand Down Expand Up @@ -133,6 +134,10 @@ pub struct LoadedProgram {
pub program: LoadedProgramType,
/// Size of account that stores the program and program data
pub account_size: usize,
/// lamoports for the program account
pub lamports: u64,
/// rent epoch for the program account
pub rent_epoch: u64,
/// Slot in which the program was (re)deployed
pub deployment_slot: Slot,
/// Slot in which this entry will become active (can be in the future)
Expand Down Expand Up @@ -282,6 +287,8 @@ impl LoadedProgram {
effective_slot: Slot,
elf_bytes: &[u8],
account_size: usize,
rent_epoch: u64,
lamports: u64,
metrics: &mut LoadProgramMetrics,
) -> Result<Self, Box<dyn std::error::Error>> {
Self::new_internal(
Expand All @@ -291,6 +298,8 @@ impl LoadedProgram {
effective_slot,
elf_bytes,
account_size,
rent_epoch,
lamports,
metrics,
false, /* reloading */
)
Expand All @@ -311,6 +320,8 @@ impl LoadedProgram {
effective_slot: Slot,
elf_bytes: &[u8],
account_size: usize,
rent_epoch: u64,
lamports: u64,
metrics: &mut LoadProgramMetrics,
) -> Result<Self, Box<dyn std::error::Error>> {
Self::new_internal(
Expand All @@ -320,18 +331,23 @@ impl LoadedProgram {
effective_slot,
elf_bytes,
account_size,
rent_epoch,
lamports,
metrics,
true, /* reloading */
)
}

#[allow(clippy::too_many_arguments)]
fn new_internal(
loader_key: &Pubkey,
program_runtime_environment: Arc<BuiltinProgram<InvokeContext<'static>>>,
deployment_slot: Slot,
effective_slot: Slot,
elf_bytes: &[u8],
account_size: usize,
rent_epoch: u64,
lamports: u64,
metrics: &mut LoadProgramMetrics,
reloading: bool,
) -> Result<Self, Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -371,6 +387,8 @@ impl LoadedProgram {
Ok(Self {
deployment_slot,
account_size,
rent_epoch,
lamports,
effective_slot,
tx_usage_counter: AtomicU64::new(0),
program,
Expand Down Expand Up @@ -402,6 +420,8 @@ impl LoadedProgram {
tx_usage_counter: AtomicU64::new(self.tx_usage_counter.load(Ordering::Relaxed)),
ix_usage_counter: AtomicU64::new(self.ix_usage_counter.load(Ordering::Relaxed)),
latest_access_slot: AtomicU64::new(self.latest_access_slot.load(Ordering::Relaxed)),
rent_epoch: self.rent_epoch,
lamports: self.lamports,
})
}

Expand All @@ -423,6 +443,8 @@ impl LoadedProgram {
program: LoadedProgramType::Builtin(BuiltinProgram::new_builtin(function_registry)),
ix_usage_counter: AtomicU64::new(0),
latest_access_slot: AtomicU64::new(0),
lamports: 0,
rent_epoch: RENT_EXEMPT_RENT_EPOCH,
}
}

Expand All @@ -435,6 +457,8 @@ impl LoadedProgram {
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::new(0),
lamports: 0,
rent_epoch: 0,
};
debug_assert!(tombstone.is_tombstone());
tombstone
Expand Down Expand Up @@ -1164,7 +1188,7 @@ mod tests {
assert_matches::assert_matches,
percentage::Percentage,
solana_rbpf::program::BuiltinProgram,
solana_sdk::{clock::Slot, pubkey::Pubkey},
solana_sdk::{clock::Slot, pubkey::Pubkey, rent_collector::RENT_EXEMPT_RENT_EPOCH},
std::{
ops::ControlFlow,
sync::{
Expand Down Expand Up @@ -1204,6 +1228,8 @@ mod tests {
tx_usage_counter: usage_counter,
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::new(deployment_slot),
rent_epoch: 0,
lamports: 0,
})
}

Expand All @@ -1216,6 +1242,8 @@ mod tests {
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::default(),
rent_epoch: RENT_EXEMPT_RENT_EPOCH,
lamports: 0,
})
}

Expand Down Expand Up @@ -1246,6 +1274,8 @@ mod tests {
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::default(),
rent_epoch: 0,
lamports: 0,
}
.to_unloaded()
.expect("Failed to unload the program"),
Expand Down Expand Up @@ -1668,6 +1698,8 @@ mod tests {
Arc::new(LoadedProgram {
program: old,
account_size: 0,
lamports: 0,
rent_epoch: 0,
deployment_slot: 10,
effective_slot: 11,
tx_usage_counter: AtomicU64::default(),
Expand All @@ -1680,6 +1712,8 @@ mod tests {
Arc::new(LoadedProgram {
program: new,
account_size: 0,
lamports: 0,
rent_epoch: 0,
deployment_slot: 10,
effective_slot: 11,
tx_usage_counter: AtomicU64::default(),
Expand All @@ -1706,6 +1740,8 @@ mod tests {
program: old,
account_size: 0,
deployment_slot: 10,
lamports: 0,
rent_epoch: 0,
effective_slot: 11,
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
Expand All @@ -1717,6 +1753,8 @@ mod tests {
Arc::new(LoadedProgram {
program: new,
account_size: 0,
lamports: 0,
rent_epoch: 0,
deployment_slot: 10,
effective_slot: 11,
tx_usage_counter: AtomicU64::default(),
Expand Down Expand Up @@ -1876,6 +1914,8 @@ mod tests {
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::default(),
rent_epoch: RENT_EXEMPT_RENT_EPOCH,
lamports: 0,
});
cache.assign_program(program1, updated_program.clone());

Expand Down Expand Up @@ -2411,6 +2451,8 @@ mod tests {
account_size: 0,
deployment_slot: 0,
effective_slot: 0,
lamports: 0,
rent_epoch: 0,
tx_usage_counter: AtomicU64::default(),
ix_usage_counter: AtomicU64::default(),
latest_access_slot: AtomicU64::default(),
Expand Down
29 changes: 26 additions & 3 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use {
loader_v4, native_loader,
program_utils::limited_deserialize,
pubkey::Pubkey,
rent_collector::RENT_EXEMPT_RENT_EPOCH,
saturating_add_assign,
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
transaction_context::{IndexOfAccount, InstructionContext, TransactionContext},
Expand All @@ -65,6 +66,8 @@ pub fn load_program_from_bytes(
programdata: &[u8],
loader_key: &Pubkey,
account_size: usize,
rent_epoch: u64,
lamports: u64,
deployment_slot: Slot,
program_runtime_environment: Arc<BuiltinProgram<InvokeContext<'static>>>,
reloading: bool,
Expand All @@ -80,6 +83,8 @@ pub fn load_program_from_bytes(
effective_slot,
programdata,
account_size,
rent_epoch,
lamports,
load_program_metrics,
)
}
Expand All @@ -91,6 +96,8 @@ pub fn load_program_from_bytes(
effective_slot,
programdata,
account_size,
rent_epoch,
lamports,
load_program_metrics,
)
}
Expand All @@ -103,7 +110,8 @@ pub fn load_program_from_bytes(

macro_rules! deploy_program {
($invoke_context:expr, $program_id:expr, $loader_key:expr,
$account_size:expr, $slot:expr, $drop:expr, $new_programdata:expr $(,)?) => {{
$account_size:expr, $lamports:expr,
$slot:expr, $drop:expr, $new_programdata:expr $(,)?) => {{
let mut load_program_metrics = LoadProgramMetrics::default();
let mut register_syscalls_time = Measure::start("register_syscalls_time");
let deployment_program_runtime_environment = create_program_runtime_environment_v1(
Expand Down Expand Up @@ -142,6 +150,8 @@ macro_rules! deploy_program {
$new_programdata,
$loader_key,
$account_size,
RENT_EXEMPT_RENT_EPOCH,
$lamports,
$slot,
$invoke_context.programs_modified_by_tx.environments.program_runtime_v1.clone(),
true,
Expand Down Expand Up @@ -523,7 +533,8 @@ fn process_loader_upgradeable_instruction(
ic_logger_msg!(log_collector, "Program account too small");
return Err(InstructionError::AccountDataTooSmall);
}
if program.get_lamports() < rent.minimum_balance(program.get_data().len()) {
let lamports = program.get_lamports();
if lamports < rent.minimum_balance(program.get_data().len()) {
ic_logger_msg!(log_collector, "Program account not rent-exempt");
return Err(InstructionError::ExecutableAccountNotRentExempt);
}
Expand Down Expand Up @@ -623,6 +634,7 @@ fn process_loader_upgradeable_instruction(
new_program_id,
&owner_id,
UpgradeableLoaderState::size_of_program().saturating_add(programdata_len),
lamports,
clock.slot,
{
drop(buffer);
Expand Down Expand Up @@ -714,6 +726,7 @@ fn process_loader_upgradeable_instruction(
return Err(InstructionError::InvalidAccountData);
}
let new_program_id = *program.get_key();
let lamports = program.get_lamports();
drop(program);

// Verify Buffer account
Expand Down Expand Up @@ -802,6 +815,7 @@ fn process_loader_upgradeable_instruction(
new_program_id,
program_id,
UpgradeableLoaderState::size_of_program().saturating_add(programdata_len),
lamports,
clock.slot,
{
drop(buffer);
Expand Down Expand Up @@ -1140,6 +1154,7 @@ fn process_loader_upgradeable_instruction(
return Err(InstructionError::InvalidAccountOwner);
}
let program_key = *program_account.get_key();
let lamports = program_account.get_lamports();
match program_account.get_state()? {
UpgradeableLoaderState::Program {
programdata_address,
Expand Down Expand Up @@ -1238,6 +1253,7 @@ fn process_loader_upgradeable_instruction(
program_key,
&program_id,
UpgradeableLoaderState::size_of_program().saturating_add(new_len),
lamports,
clock_slot,
{
drop(programdata_account);
Expand Down Expand Up @@ -1503,6 +1519,8 @@ pub mod test_utils {
account.data(),
owner,
account.data().len(),
account.rent_epoch(),
account.lamports(),
0,
program_runtime_environment.clone(),
false,
Expand Down Expand Up @@ -3714,9 +3732,10 @@ mod tests {
program_id,
&bpf_loader_upgradeable::id(),
elf.len(),
102,
2,
{},
&elf
&elf,
);
Ok(())
}
Expand All @@ -3735,6 +3754,8 @@ mod tests {
tx_usage_counter: AtomicU64::new(100),
ix_usage_counter: AtomicU64::new(100),
latest_access_slot: AtomicU64::new(0),
rent_epoch: 0,
lamports: 0,
};
invoke_context
.programs_modified_by_tx
Expand Down Expand Up @@ -3775,6 +3796,8 @@ mod tests {
tx_usage_counter: AtomicU64::new(100),
ix_usage_counter: AtomicU64::new(100),
latest_access_slot: AtomicU64::new(0),
rent_epoch: 0,
lamports: 0,
};
invoke_context
.programs_modified_by_tx
Expand Down
Loading

0 comments on commit 45a967b

Please sign in to comment.