Skip to content

Commit

Permalink
Loosen CPI restrictions and charge compute for ix data len (solana-la…
Browse files Browse the repository at this point in the history
…bs#26653)

* Loosen CPI restrictions and charge compute for ix data len

* Address feedback

* use explicit casting

* more feedback
  • Loading branch information
jstarry authored Jul 24, 2022
1 parent d9c7bc7 commit 2335f69
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 61 deletions.
43 changes: 31 additions & 12 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ 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_INSTRUCTION_DATA_TOO_LARGE = 9;
static const uint8_t TEST_INSTRUCTION_META_TOO_LARGE = 10;
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;
Expand All @@ -31,6 +31,7 @@ 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 int MINT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
Expand Down Expand Up @@ -76,7 +77,7 @@ uint64_t do_nested_invokes(uint64_t num_nested_invokes,
}

extern uint64_t entrypoint(const uint8_t *input) {
sol_log("Invoke C program");
sol_log("invoke C program");

SolAccountInfo accounts[13];
SolParameters params = (SolParameters){.ka = accounts};
Expand Down Expand Up @@ -480,28 +481,29 @@ extern uint64_t entrypoint(const uint8_t *input) {
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));
break;
}
case TEST_INSTRUCTION_DATA_TOO_LARGE: {
sol_log("Test instruction data too large");
case TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED: {
sol_log("Test max instruction data len exceeded");
SolAccountMeta arguments[] = {};
uint8_t *data = sol_calloc(1500, 1);
uint64_t data_len = MAX_CPI_INSTRUCTION_DATA_LEN + 1;
uint8_t *data = sol_calloc(data_len, 1);
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, 1500};
data, data_len};
const SolSignerSeeds signers_seeds[] = {};
sol_assert(SUCCESS == sol_invoke_signed(
&instruction, accounts, SOL_ARRAY_SIZE(accounts),
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));

break;
}
case TEST_INSTRUCTION_META_TOO_LARGE: {
sol_log("Test instruction meta too large");
SolAccountMeta *arguments = sol_calloc(40, sizeof(SolAccountMeta));
sol_log_64(0, 0, 0, 0, (uint64_t)arguments);
case TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED: {
sol_log("Test max instruction accounts exceeded");
uint64_t accounts_len = MAX_CPI_INSTRUCTION_ACCOUNTS + 1;
SolAccountMeta *arguments = sol_calloc(accounts_len, sizeof(SolAccountMeta));
sol_assert(0 != arguments);
uint8_t data[] = {};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, 40, data,
arguments, accounts_len, data,
SOL_ARRAY_SIZE(data)};
const SolSignerSeeds signers_seeds[] = {};
sol_assert(SUCCESS == sol_invoke_signed(
Expand All @@ -510,6 +512,23 @@ extern uint64_t entrypoint(const uint8_t *input) {

break;
}
case TEST_MAX_ACCOUNT_INFOS_EXCEEDED: {
sol_log("Test max account infos exceeded");
SolAccountMeta arguments[] = {};
uint64_t account_infos_len = MAX_CPI_ACCOUNT_INFOS + 1;
SolAccountInfo *account_infos = sol_calloc(account_infos_len, sizeof(SolAccountInfo));
sol_assert(0 != account_infos);
uint8_t data[] = {};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
const SolSignerSeeds signers_seeds[] = {};
sol_assert(SUCCESS == sol_invoke_signed(
&instruction, account_infos, account_infos_len,
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));

break;
}
case TEST_RETURN_ERROR: {
sol_log("Test return error");
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, false, true}};
Expand Down
5 changes: 3 additions & 2 deletions programs/bpf/rust/invoke/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ 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_INSTRUCTION_DATA_TOO_LARGE: u8 = 9;
pub const TEST_INSTRUCTION_META_TOO_LARGE: u8 = 10;
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;
Expand All @@ -21,6 +21,7 @@ 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 MINT_INDEX: usize = 0;
pub const ARGUMENT_INDEX: usize = 1;
Expand Down
31 changes: 21 additions & 10 deletions programs/bpf/rust/invoke/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use {
program::{get_return_data, invoke, invoke_signed, set_return_data},
program_error::ProgramError,
pubkey::{Pubkey, PubkeyError},
syscalls::{
MAX_CPI_ACCOUNT_INFOS, MAX_CPI_INSTRUCTION_ACCOUNTS, MAX_CPI_INSTRUCTION_DATA_LEN,
},
system_instruction,
},
};
Expand Down Expand Up @@ -554,21 +557,29 @@ fn process_instruction(
&[&[b"You pass butter", &[bump_seed1]]],
)?;
}
TEST_INSTRUCTION_DATA_TOO_LARGE => {
msg!("Test instruction data too large");
TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED => {
msg!("Test max instruction data len exceeded");
let data_len = MAX_CPI_INSTRUCTION_DATA_LEN.saturating_add(1) as usize;
let instruction =
create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![0; 1500]);
create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![0; data_len]);
invoke_signed(&instruction, &[], &[])?;
}
TEST_INSTRUCTION_META_TOO_LARGE => {
msg!("Test instruction metas too large");
let instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(&Pubkey::default(), false, false); 40],
vec![],
);
TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED => {
msg!("Test max instruction accounts exceeded");
let default_key = Pubkey::default();
let account_metas_len = (MAX_CPI_INSTRUCTION_ACCOUNTS as usize).saturating_add(1);
let account_metas = vec![(&default_key, false, false); account_metas_len];
let instruction =
create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &account_metas, vec![]);
invoke_signed(&instruction, &[], &[])?;
}
TEST_MAX_ACCOUNT_INFOS_EXCEEDED => {
msg!("Test max account infos exceeded");
let instruction = create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![]);
let account_infos_len = (MAX_CPI_ACCOUNT_INFOS as usize).saturating_add(1);
let account_infos = vec![accounts[0].clone(); account_infos_len];
invoke_signed(&instruction, &account_infos, &[])?;
}
TEST_RETURN_ERROR => {
msg!("Test return error");
let instruction = create_instruction(
Expand Down
Loading

0 comments on commit 2335f69

Please sign in to comment.