Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use {
runtime_config::RuntimeConfig,
},
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount},
account::{Account, AccountSharedData},
account_info::AccountInfo,
clock::Slot,
entrypoint::{deserialize, ProgramResult, SUCCESS},
Expand Down Expand Up @@ -291,23 +291,12 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
}
_ => {}
}
if borrowed_account.is_executable() != account_info.executable {
borrowed_account
.set_executable(account_info.executable)
.unwrap();
}
// Change the owner at the end so that we are allowed to change the lamports and data before
if borrowed_account.get_owner() != account_info.owner {
borrowed_account
.set_owner(account_info.owner.as_ref())
.unwrap();
}
drop(borrowed_account);
let account = transaction_context
.get_account_at_index(instruction_account.index_in_transaction)
.unwrap()
.borrow();
assert_eq!(account.rent_epoch(), account_info.rent_epoch);
if instruction_account.is_writable {
account_indices.push((instruction_account.index_in_caller, account_info_index));
}
Expand Down
47 changes: 21 additions & 26 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ static const uint8_t TEST_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER = 12;
static const uint8_t TEST_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE = 13;
static const uint8_t TEST_WRITABLE_DEESCALATION_WRITABLE = 14;
static const uint8_t TEST_NESTED_INVOKE_TOO_DEEP = 15;
static const uint8_t TEST_EXECUTABLE_LAMPORTS = 16;
static const uint8_t TEST_CALL_PRECOMPILE = 17;
static const uint8_t ADD_LAMPORTS = 18;
static const uint8_t TEST_RETURN_DATA_TOO_LARGE = 19;
static const uint8_t TEST_DUPLICATE_PRIVILEGE_ESCALATION_SIGNER = 20;
static const uint8_t TEST_DUPLICATE_PRIVILEGE_ESCALATION_WRITABLE = 21;
static const uint8_t TEST_MAX_ACCOUNT_INFOS_EXCEEDED = 22;
static const uint8_t TEST_CALL_PRECOMPILE = 16;
static const uint8_t ADD_LAMPORTS = 17;
static const uint8_t TEST_RETURN_DATA_TOO_LARGE = 18;
static const uint8_t TEST_DUPLICATE_PRIVILEGE_ESCALATION_SIGNER = 19;
static const uint8_t TEST_DUPLICATE_PRIVILEGE_ESCALATION_WRITABLE = 20;
static const uint8_t TEST_MAX_ACCOUNT_INFOS_EXCEEDED = 21;

static const int MINT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
Expand Down Expand Up @@ -320,6 +319,21 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(accounts[ARGUMENT_INDEX].data[i] == 0);
}
}

sol_log("Test that is_executable and rent_epoch are ignored");
{
accounts[INVOKED_ARGUMENT_INDEX].executable = true;
accounts[INVOKED_ARGUMENT_INDEX].rent_epoch += 1;
SolAccountMeta arguments[] = {
{accounts[INVOKED_ARGUMENT_INDEX].key, true, false}};
uint8_t data[] = {RETURN_OK};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};

sol_assert(SUCCESS ==
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}
break;
}
case TEST_PRIVILEGE_ESCALATION_SIGNER: {
Expand Down Expand Up @@ -593,25 +607,6 @@ extern uint64_t entrypoint(const uint8_t *input) {
do_nested_invokes(5, accounts, params.ka_num);
break;
}
case TEST_EXECUTABLE_LAMPORTS: {
sol_log("Test executable lamports");
accounts[ARGUMENT_INDEX].executable = true;
*accounts[ARGUMENT_INDEX].lamports -= 1;
*accounts[DERIVED_KEY1_INDEX].lamports +=1;
SolAccountMeta arguments[] = {
{accounts[ARGUMENT_INDEX].key, true, false},
{accounts[DERIVED_KEY1_INDEX].key, true, false},
};
uint8_t data[] = {ADD_LAMPORTS, 0, 0, 0};
SolPubkey program_id;
sol_memcpy(&program_id, params.program_id, sizeof(SolPubkey));
const SolInstruction instruction = {&program_id,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts));
*accounts[ARGUMENT_INDEX].lamports += 1;
break;
}
case TEST_CALL_PRECOMPILE: {
sol_log("Test calling precompile from cpi");
SolAccountMeta arguments[] = {};
Expand Down
13 changes: 6 additions & 7 deletions programs/bpf/rust/invoke/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ pub const TEST_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER: u8 = 12;
pub const TEST_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE: u8 = 13;
pub const TEST_WRITABLE_DEESCALATION_WRITABLE: u8 = 14;
pub const TEST_NESTED_INVOKE_TOO_DEEP: u8 = 15;
pub const TEST_EXECUTABLE_LAMPORTS: u8 = 16;
pub const TEST_CALL_PRECOMPILE: u8 = 17;
pub const ADD_LAMPORTS: u8 = 18;
pub const TEST_RETURN_DATA_TOO_LARGE: u8 = 19;
pub const TEST_DUPLICATE_PRIVILEGE_ESCALATION_SIGNER: u8 = 20;
pub const TEST_DUPLICATE_PRIVILEGE_ESCALATION_WRITABLE: u8 = 21;
pub const TEST_MAX_ACCOUNT_INFOS_EXCEEDED: u8 = 22;
pub const TEST_CALL_PRECOMPILE: u8 = 16;
pub const ADD_LAMPORTS: u8 = 17;
pub const TEST_RETURN_DATA_TOO_LARGE: u8 = 18;
pub const TEST_DUPLICATE_PRIVILEGE_ESCALATION_SIGNER: u8 = 19;
pub const TEST_DUPLICATE_PRIVILEGE_ESCALATION_WRITABLE: u8 = 20;
pub const TEST_MAX_ACCOUNT_INFOS_EXCEEDED: u8 = 21;

pub const MINT_INDEX: usize = 0;
pub const ARGUMENT_INDEX: usize = 1;
Expand Down
32 changes: 0 additions & 32 deletions programs/bpf/rust/invoke/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,38 +639,6 @@ fn process_instruction(
TEST_NESTED_INVOKE_TOO_DEEP => {
let _ = do_nested_invokes(5, accounts);
}
TEST_EXECUTABLE_LAMPORTS => {
msg!("Test executable lamports");
let mut accounts = accounts.to_vec();

// set account to executable and subtract lamports
accounts[ARGUMENT_INDEX].executable = true;
{
let mut lamports = (*accounts[ARGUMENT_INDEX].lamports).borrow_mut();
**lamports = (*lamports).saturating_sub(1);
}
// add lamports to dest account
{
let mut lamports = (*accounts[DERIVED_KEY1_INDEX].lamports).borrow_mut();
**lamports = (*lamports).saturating_add(1);
}

let instruction = create_instruction(
*program_id,
&[
(accounts[ARGUMENT_INDEX].key, true, false),
(accounts[DERIVED_KEY1_INDEX].key, true, false),
],
vec![ADD_LAMPORTS, 0, 0, 0],
);
let _ = invoke(&instruction, &accounts);

// reset executable account
{
let mut lamports = (*accounts[ARGUMENT_INDEX].lamports).borrow_mut();
**lamports = (*lamports).saturating_add(1);
}
}
TEST_CALL_PRECOMPILE => {
msg!("Test calling precompiled program from cpi");
let instruction =
Expand Down
8 changes: 1 addition & 7 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,7 @@ fn test_program_bpf_invoke_sanity() {
invoked_program_id.clone(),
invoked_program_id.clone(),
invoked_program_id.clone(),
invoked_program_id.clone(),
],
Languages::Rust => vec![
system_program::id(),
Expand Down Expand Up @@ -1310,13 +1311,6 @@ fn test_program_bpf_invoke_sanity() {
None,
);

do_invoke_failure_test_local(
TEST_EXECUTABLE_LAMPORTS,
TransactionError::InstructionError(0, InstructionError::ExecutableLamportChange),
&[invoke_program_id.clone()],
None,
);

do_invoke_failure_test_local(
TEST_CALL_PRECOMPILE,
TransactionError::InstructionError(0, InstructionError::ProgramFailedToComplete),
Expand Down
11 changes: 9 additions & 2 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ where
.get_current_instruction_context()
.map_err(SyscallError::InstructionError)?;
let mut accounts = Vec::with_capacity(instruction_accounts.len().saturating_add(1));
let is_disable_cpi_setting_executable_and_rent_epoch_active = invoke_context
.feature_set
.is_active(&disable_cpi_setting_executable_and_rent_epoch::id());

let program_account_index = program_indices
.last()
Expand Down Expand Up @@ -680,7 +683,9 @@ where
}
_ => {}
}
if callee_account.is_executable() != caller_account.executable {
if !is_disable_cpi_setting_executable_and_rent_epoch_active
&& callee_account.is_executable() != caller_account.executable
{
callee_account
.set_executable(caller_account.executable)
.map_err(SyscallError::InstructionError)?;
Expand All @@ -696,7 +701,9 @@ where
.transaction_context
.get_account_at_index(instruction_account.index_in_transaction)
.map_err(SyscallError::InstructionError)?;
if callee_account.borrow().rent_epoch() != caller_account.rent_epoch {
if !is_disable_cpi_setting_executable_and_rent_epoch_active
&& callee_account.borrow().rent_epoch() != caller_account.rent_epoch
{
if invoke_context
.feature_set
.is_active(&enable_early_verification_of_account_modifications::id())
Expand Down
8 changes: 4 additions & 4 deletions programs/bpf_loader/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ use {
entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS},
feature_set::{
self, blake3_syscall_enabled, check_physical_overlapping, check_slice_translation_size,
curve25519_syscall_enabled, disable_fees_sysvar,
enable_early_verification_of_account_modifications, libsecp256k1_0_5_upgrade_enabled,
limit_secp256k1_recovery_id, prevent_calling_precompiles_as_programs,
syscall_saturated_math,
curve25519_syscall_enabled, disable_cpi_setting_executable_and_rent_epoch,
disable_fees_sysvar, enable_early_verification_of_account_modifications,
libsecp256k1_0_5_upgrade_enabled, limit_secp256k1_recovery_id,
prevent_calling_precompiles_as_programs, syscall_saturated_math,
},
hash::{Hasher, HASH_BYTES},
instruction::{
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/feature_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@ pub mod incremental_snapshot_only_incremental_hash_calculation {
solana_sdk::declare_id!("25vqsfjk7Nv1prsQJmA4Xu1bN61s8LXCBGUPp8Rfy1UF");
}

pub mod disable_cpi_setting_executable_and_rent_epoch {
solana_sdk::declare_id!("B9cdB55u4jQsDNsdTK525yE9dmSc5Ga7YBaBrDFvEhM9");
}

lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
Expand Down Expand Up @@ -614,6 +618,7 @@ lazy_static! {
(sign_repair_requests::id(), "sign repair requests #26834"),
(concurrent_replay_of_forks::id(), "Allow slots from different forks to be replayed concurrently #26465"),
(incremental_snapshot_only_incremental_hash_calculation::id(), "only hash accounts in incremental snapshot during incremental snapshot creation #26799"),
(disable_cpi_setting_executable_and_rent_epoch::id(), "disable setting is_executable and_rent_epoch in CPI #26987"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
Expand Down