Skip to content

Commit

Permalink
Adjusts tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Jul 11, 2024
1 parent ad6a0c0 commit d03075e
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 75 deletions.
26 changes: 23 additions & 3 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1723,13 +1723,21 @@ mod tests {

// Case: Account not a program
program_account.set_executable(false);
process_instruction(
mock_process_instruction(
&loader_id,
&[0],
vec![0],
&[],
vec![(program_id, program_account)],
Vec::new(),
Err(InstructionError::IncorrectProgramId),
Entrypoint::vm,
|invoke_context| {
let mut feature_set = invoke_context.get_feature_set().clone();
feature_set.deactivate(&infer_account_is_executable_flag::id());
invoke_context.mock_set_feature_set(Arc::new(feature_set));
test_utils::load_all_invoked_programs(invoke_context);
},
|_invoke_context| {},
);
}

Expand Down Expand Up @@ -2404,10 +2412,22 @@ mod tests {
.unwrap()
.1
.set_executable(false);
process_instruction(
let instruction_data = bincode::serialize(&UpgradeableLoaderInstruction::Upgrade).unwrap();
mock_process_instruction(
&bpf_loader_upgradeable::id(),
Vec::new(),
&instruction_data,
transaction_accounts,
instruction_accounts,
Err(InstructionError::AccountNotExecutable),
Entrypoint::vm,
|invoke_context| {
let mut feature_set = invoke_context.get_feature_set().clone();
feature_set.deactivate(&infer_account_is_executable_flag::id());
invoke_context.mock_set_feature_set(Arc::new(feature_set));
test_utils::load_all_invoked_programs(invoke_context);
},
|_invoke_context| {},
);

// Case: Program account now owned by loader
Expand Down
64 changes: 38 additions & 26 deletions programs/sbf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,31 @@
static const uint8_t TEST_SUCCESS = 1;
static const uint8_t TEST_PRIVILEGE_ESCALATION_SIGNER = 2;
static const uint8_t TEST_PRIVILEGE_ESCALATION_WRITABLE = 3;
static const uint8_t TEST_PPROGRAM_NOT_EXECUTABLE = 4;
static const uint8_t TEST_EMPTY_ACCOUNTS_SLICE = 5;
static const uint8_t TEST_CAP_SEEDS = 6;
static const uint8_t TEST_CAP_SIGNERS = 7;
static const uint8_t TEST_ALLOC_ACCESS_VIOLATION = 8;
static const uint8_t TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED = 9;
static const uint8_t TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED = 10;
static const uint8_t TEST_RETURN_ERROR = 11;
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_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 uint8_t TEST_PPROGRAM_NOT_OWNED_BY_LOADER = 4;
static const uint8_t TEST_PPROGRAM_NOT_EXECUTABLE = 5;
static const uint8_t TEST_EMPTY_ACCOUNTS_SLICE = 6;
static const uint8_t TEST_CAP_SEEDS = 7;
static const uint8_t TEST_CAP_SIGNERS = 8;
static const uint8_t TEST_ALLOC_ACCESS_VIOLATION = 9;
static const uint8_t TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED = 10;
static const uint8_t TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED = 11;
static const uint8_t TEST_RETURN_ERROR = 12;
static const uint8_t TEST_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER = 13;
static const uint8_t TEST_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE = 14;
static const uint8_t TEST_WRITABLE_DEESCALATION_WRITABLE = 15;
static const uint8_t TEST_NESTED_INVOKE_TOO_DEEP = 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;
// TEST_CPI_INVALID_* must match the definitions in
// https://github.com/solana-labs/solana/blob/master/programs/sbf/rust/invoke/src/instructions.rs
static const uint8_t TEST_CPI_INVALID_KEY_POINTER = 34;
static const uint8_t TEST_CPI_INVALID_OWNER_POINTER = 35;
static const uint8_t TEST_CPI_INVALID_LAMPORTS_POINTER = 36;
static const uint8_t TEST_CPI_INVALID_DATA_POINTER = 37;
static const uint8_t TEST_CPI_INVALID_KEY_POINTER = 35;
static const uint8_t TEST_CPI_INVALID_OWNER_POINTER = 36;
static const uint8_t TEST_CPI_INVALID_LAMPORTS_POINTER = 37;
static const uint8_t TEST_CPI_INVALID_DATA_POINTER = 38;

static const int MINT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
Expand All @@ -51,6 +52,7 @@ static const int SYSTEM_PROGRAM_INDEX = 9;
static const int FROM_INDEX = 10;
static const int ED25519_PROGRAM_INDEX = 11;
static const int INVOKE_PROGRAM_INDEX = 12;
static const int UNEXECUTABLE_PROGRAM_INDEX = 13;

uint64_t do_nested_invokes(uint64_t num_nested_invokes,
SolAccountInfo *accounts, uint64_t num_accounts) {
Expand Down Expand Up @@ -84,7 +86,7 @@ uint64_t do_nested_invokes(uint64_t num_nested_invokes,
extern uint64_t entrypoint(const uint8_t *input) {
sol_log("invoke C program");

SolAccountInfo accounts[13];
SolAccountInfo accounts[14];
SolParameters params = (SolParameters){.ka = accounts};

if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(accounts))) {
Expand Down Expand Up @@ -374,12 +376,22 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts));
break;
}
case TEST_PPROGRAM_NOT_OWNED_BY_LOADER: {
sol_log("Test program not owned by loader");
SolAccountMeta arguments[] = {
{accounts[INVOKED_ARGUMENT_INDEX].key, false, false}};
uint8_t data[] = {RETURN_OK};
const SolInstruction instruction = {accounts[ARGUMENT_INDEX].key, arguments,
SOL_ARRAY_SIZE(arguments), data,
SOL_ARRAY_SIZE(data)};
return sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts));
}
case TEST_PPROGRAM_NOT_EXECUTABLE: {
sol_log("Test program not executable");
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {VERIFY_PRIVILEGE_ESCALATION};
const SolInstruction instruction = {accounts[ARGUMENT_INDEX].key, arguments,
{accounts[INVOKED_ARGUMENT_INDEX].key, false, false}};
uint8_t data[] = {RETURN_OK};
const SolInstruction instruction = {accounts[UNEXECUTABLE_PROGRAM_INDEX].key, arguments,
SOL_ARRAY_SIZE(arguments), data,
SOL_ARRAY_SIZE(data)};
return sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts));
Expand Down
4 changes: 2 additions & 2 deletions programs/sbf/rust/deprecated_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use solana_program::{

pub const REALLOC: u8 = 1;
pub const REALLOC_EXTEND_FROM_SLICE: u8 = 12;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS: u8 = 28;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_NESTED: u8 = 29;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS: u8 = 29;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_NESTED: u8 = 30;

#[derive(Debug, PartialEq)]
struct SStruct {
Expand Down
13 changes: 11 additions & 2 deletions programs/sbf/rust/invoke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,20 @@ fn process_instruction<'a>(
invoked_instruction.accounts[0].is_writable = true;
invoke(&invoked_instruction, accounts)?;
}
TEST_PPROGRAM_NOT_OWNED_BY_LOADER => {
msg!("Test program not owned by loader");
let instruction = create_instruction(
*accounts[ARGUMENT_INDEX].key,
&[(accounts[INVOKED_ARGUMENT_INDEX].key, false, false)],
vec![RETURN_OK],
);
invoke(&instruction, accounts)?;
}
TEST_PPROGRAM_NOT_EXECUTABLE => {
msg!("Test program not executable");
let instruction = create_instruction(
*accounts[ARGUMENT_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, true, true)],
*accounts[UNEXECUTABLE_PROGRAM_INDEX].key,
&[(accounts[INVOKED_ARGUMENT_INDEX].key, false, false)],
vec![RETURN_OK],
);
invoke(&instruction, accounts)?;
Expand Down
78 changes: 40 additions & 38 deletions programs/sbf/rust/invoke_dep/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,45 @@
pub const TEST_SUCCESS: u8 = 1;
pub const TEST_PRIVILEGE_ESCALATION_SIGNER: u8 = 2;
pub const TEST_PRIVILEGE_ESCALATION_WRITABLE: u8 = 3;
pub const TEST_PPROGRAM_NOT_EXECUTABLE: u8 = 4;
pub const TEST_EMPTY_ACCOUNTS_SLICE: u8 = 5;
pub const TEST_CAP_SEEDS: u8 = 6;
pub const TEST_CAP_SIGNERS: u8 = 7;
pub const TEST_ALLOC_ACCESS_VIOLATION: u8 = 8;
pub const TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED: u8 = 9;
pub const TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED: u8 = 10;
pub const TEST_RETURN_ERROR: u8 = 11;
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_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 TEST_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLEE: u8 = 22;
pub const TEST_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLEE_NESTED: u8 = 23;
pub const TEST_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLER: u8 = 24;
pub const TEST_FORBID_LEN_UPDATE_AFTER_OWNERSHIP_CHANGE_MOVING_DATA_POINTER: u8 = 25;
pub const TEST_FORBID_LEN_UPDATE_AFTER_OWNERSHIP_CHANGE: u8 = 26;
pub const TEST_ALLOW_WRITE_AFTER_OWNERSHIP_CHANGE_TO_CALLER: u8 = 27;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS: u8 = 28;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_NESTED: u8 = 29;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLEE_GROWS: u8 = 30;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLEE_SHRINKS_SMALLER_THAN_ORIGINAL_LEN: u8 = 31;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_CALLEE_SHRINKS: u8 = 32;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_CALLEE_SHRINKS_NESTED: u8 = 33;
pub const TEST_CPI_INVALID_KEY_POINTER: u8 = 34;
pub const TEST_CPI_INVALID_OWNER_POINTER: u8 = 35;
pub const TEST_CPI_INVALID_LAMPORTS_POINTER: u8 = 36;
pub const TEST_CPI_INVALID_DATA_POINTER: u8 = 37;
pub const TEST_CPI_CHANGE_ACCOUNT_DATA_MEMORY_ALLOCATION: u8 = 38;
pub const TEST_WRITE_ACCOUNT: u8 = 39;
pub const TEST_CALLEE_ACCOUNT_UPDATES: u8 = 40;
pub const TEST_STACK_HEAP_ZEROED: u8 = 41;
pub const TEST_PPROGRAM_NOT_OWNED_BY_LOADER: u8 = 4;
pub const TEST_PPROGRAM_NOT_EXECUTABLE: u8 = 5;
pub const TEST_EMPTY_ACCOUNTS_SLICE: u8 = 6;
pub const TEST_CAP_SEEDS: u8 = 7;
pub const TEST_CAP_SIGNERS: u8 = 8;
pub const TEST_ALLOC_ACCESS_VIOLATION: u8 = 9;
pub const TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED: u8 = 10;
pub const TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED: u8 = 11;
pub const TEST_RETURN_ERROR: u8 = 12;
pub const TEST_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER: u8 = 13;
pub const TEST_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE: u8 = 14;
pub const TEST_WRITABLE_DEESCALATION_WRITABLE: u8 = 15;
pub const TEST_NESTED_INVOKE_TOO_DEEP: 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_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLEE: u8 = 23;
pub const TEST_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLEE_NESTED: u8 = 24;
pub const TEST_FORBID_WRITE_AFTER_OWNERSHIP_CHANGE_IN_CALLER: u8 = 25;
pub const TEST_FORBID_LEN_UPDATE_AFTER_OWNERSHIP_CHANGE_MOVING_DATA_POINTER: u8 = 26;
pub const TEST_FORBID_LEN_UPDATE_AFTER_OWNERSHIP_CHANGE: u8 = 27;
pub const TEST_ALLOW_WRITE_AFTER_OWNERSHIP_CHANGE_TO_CALLER: u8 = 28;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS: u8 = 29;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_NESTED: u8 = 30;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLEE_GROWS: u8 = 31;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLEE_SHRINKS_SMALLER_THAN_ORIGINAL_LEN: u8 = 32;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_CALLEE_SHRINKS: u8 = 33;
pub const TEST_CPI_ACCOUNT_UPDATE_CALLER_GROWS_CALLEE_SHRINKS_NESTED: u8 = 34;
pub const TEST_CPI_INVALID_KEY_POINTER: u8 = 35;
pub const TEST_CPI_INVALID_OWNER_POINTER: u8 = 36;
pub const TEST_CPI_INVALID_LAMPORTS_POINTER: u8 = 37;
pub const TEST_CPI_INVALID_DATA_POINTER: u8 = 38;
pub const TEST_CPI_CHANGE_ACCOUNT_DATA_MEMORY_ALLOCATION: u8 = 39;
pub const TEST_WRITE_ACCOUNT: u8 = 40;
pub const TEST_CALLEE_ACCOUNT_UPDATES: u8 = 41;
pub const TEST_STACK_HEAP_ZEROED: u8 = 42;

pub const MINT_INDEX: usize = 0;
pub const ARGUMENT_INDEX: usize = 1;
Expand All @@ -55,3 +56,4 @@ pub const SYSTEM_PROGRAM_INDEX: usize = 9;
pub const FROM_INDEX: usize = 10;
pub const ED25519_PROGRAM_INDEX: usize = 11;
pub const INVOKE_PROGRAM_INDEX: usize = 12;
pub const UNEXECUTABLE_PROGRAM_INDEX: usize = 13;
18 changes: 15 additions & 3 deletions programs/sbf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,10 @@ fn test_program_sbf_invoke_sanity() {
let account = AccountSharedData::new(84, 0, &system_program::id());
bank.store_account(&from_keypair.pubkey(), &account);

let unexecutable_program_keypair = Keypair::new();
let account = AccountSharedData::new(1, 0, &bpf_loader::id());
bank.store_account(&unexecutable_program_keypair.pubkey(), &account);

let (derived_key1, bump_seed1) =
Pubkey::find_program_address(&[b"You pass butter"], &invoke_program_id);
let (derived_key2, bump_seed2) =
Expand All @@ -769,6 +773,7 @@ fn test_program_sbf_invoke_sanity() {
AccountMeta::new(from_keypair.pubkey(), true),
AccountMeta::new_readonly(solana_sdk::ed25519_program::id(), false),
AccountMeta::new_readonly(invoke_program_id, false),
AccountMeta::new_readonly(unexecutable_program_keypair.pubkey(), false),
];

// success cases
Expand Down Expand Up @@ -920,10 +925,17 @@ fn test_program_sbf_invoke_sanity() {
None,
);

do_invoke_failure_test_local(
TEST_PPROGRAM_NOT_OWNED_BY_LOADER,
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId),
&[argument_keypair.pubkey()],
None,
);

do_invoke_failure_test_local(
TEST_PPROGRAM_NOT_EXECUTABLE,
TransactionError::InstructionError(0, InstructionError::AccountNotExecutable),
&[],
TransactionError::InstructionError(0, InstructionError::InvalidAccountData),
&[unexecutable_program_keypair.pubkey()],
None,
);

Expand Down Expand Up @@ -4641,7 +4653,7 @@ fn test_deny_executable_write() {
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::ExecutableDataModified)
TransactionError::InstructionError(0, InstructionError::ReadonlyDataModified)
);
}
}
Expand Down
10 changes: 9 additions & 1 deletion svm/src/account_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,15 @@ mod tests {
instructions,
);

let loaded_accounts = load_accounts_aux_test(tx, &accounts, &mut error_metrics);
let mut feature_set = FeatureSet::all_enabled();
feature_set.deactivate(&feature_set::infer_account_is_executable_flag::id());
let loaded_accounts = load_accounts_with_features_and_rent(
tx,
&accounts,
&RentCollector::default(),
&mut error_metrics,
&mut feature_set,
);

assert_eq!(error_metrics.invalid_program_for_execution, 1);
assert_eq!(loaded_accounts.len(), 1);
Expand Down

0 comments on commit d03075e

Please sign in to comment.