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 14, 2024
1 parent 2ddb50d commit e834852
Show file tree
Hide file tree
Showing 11 changed files with 522 additions and 106 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 @@ -1718,6 +1748,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 @@ -1730,6 +1762,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 @@ -1756,6 +1790,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 @@ -1767,6 +1803,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 @@ -1926,6 +1964,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 @@ -2461,6 +2501,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 @@ -42,6 +42,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 @@ -66,6 +67,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 @@ -81,6 +84,8 @@ pub fn load_program_from_bytes(
effective_slot,
programdata,
account_size,
rent_epoch,
lamports,
load_program_metrics,
)
}
Expand All @@ -92,6 +97,8 @@ pub fn load_program_from_bytes(
effective_slot,
programdata,
account_size,
rent_epoch,
lamports,
load_program_metrics,
)
}
Expand All @@ -104,7 +111,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 @@ -143,6 +151,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 @@ -527,7 +537,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 @@ -627,6 +638,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 @@ -735,6 +747,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 @@ -823,6 +836,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 @@ -1188,6 +1202,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 @@ -1286,6 +1301,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 @@ -1559,6 +1575,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 @@ -3780,9 +3798,10 @@ mod tests {
program_id,
&bpf_loader_upgradeable::id(),
elf.len(),
102,
2,
{},
&elf
&elf,
);
Ok(())
}
Expand All @@ -3801,6 +3820,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 @@ -3841,6 +3862,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 e834852

Please sign in to comment.