Check CPI program is executable

This commit is contained in:
Jack May
2020-10-01 23:10:36 -07:00
committed by Michael Vines
parent c162ac27dd
commit a61d24bfa9
7 changed files with 88 additions and 42 deletions

View File

@ -1627,7 +1627,7 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"byteorder 1.3.4",
@ -1642,7 +1642,7 @@ dependencies = [
[[package]]
name = "solana-bpf-programs"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"byteorder 1.3.4",
@ -1657,7 +1657,7 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-bpf-rust-128bit-dep",
"solana-sdk",
@ -1665,21 +1665,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"byteorder 1.3.4",
"solana-sdk",
@ -1687,14 +1687,14 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-dup-accounts"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-error-handling"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"num-derive 0.2.5",
"num-traits",
@ -1704,14 +1704,14 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-external-spend"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-invoke"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-bpf-rust-invoked",
"solana-sdk",
@ -1719,21 +1719,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-invoked"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-bpf-rust-many-args-dep",
"solana-sdk",
@ -1741,28 +1741,28 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-bpf-rust-param-passing-dep",
"solana-sdk",
@ -1770,21 +1770,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-config-program"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"chrono",
@ -1796,7 +1796,7 @@ dependencies = [
[[package]]
name = "solana-crate-features"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"backtrace",
"bytes 0.4.12",
@ -1819,7 +1819,7 @@ dependencies = [
[[package]]
name = "solana-logger"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"env_logger",
"lazy_static",
@ -1828,7 +1828,7 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"jemalloc-ctl",
"jemallocator",
@ -1839,7 +1839,7 @@ dependencies = [
[[package]]
name = "solana-metrics"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"env_logger",
"gethostname",
@ -1851,7 +1851,7 @@ dependencies = [
[[package]]
name = "solana-rayon-threadlimit"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"lazy_static",
"num_cpus",
@ -1859,7 +1859,7 @@ dependencies = [
[[package]]
name = "solana-runtime"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"blake3",
@ -1894,7 +1894,7 @@ dependencies = [
[[package]]
name = "solana-sdk"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"assert_matches",
"bincode",
@ -1930,7 +1930,7 @@ dependencies = [
[[package]]
name = "solana-sdk-macro"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bs58",
"proc-macro2 1.0.18",
@ -1941,7 +1941,7 @@ dependencies = [
[[package]]
name = "solana-stake-program"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"log",
@ -1958,7 +1958,7 @@ dependencies = [
[[package]]
name = "solana-vote-program"
version = "1.2.30"
version = "1.2.32"
dependencies = [
"bincode",
"log",

View File

@ -7,6 +7,7 @@
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 int MINT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
@ -92,8 +93,9 @@ extern uint64_t entrypoint(const uint8_t *input) {
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{&nonce1, 1}};
SolPubkey address;
sol_assert(SUCCESS == sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
params.program_id, &address));
sol_assert(SUCCESS ==
sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
params.program_id, &address));
sol_assert(SolPubkey_same(&address, accounts[DERIVED_KEY1_INDEX].key));
}
@ -203,6 +205,16 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
break;
}
case TEST_PPROGRAM_NOT_EXECUTABLE: {
sol_log("Test program not executable");
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_VERIFY_PRIVILEGE_ESCALATION};
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));
}
default:
sol_panic();
}

View File

@ -12,6 +12,10 @@ extern uint64_t entrypoint(const uint8_t *input) {
return ERROR_INVALID_ARGUMENT;
}
if (params.data_len == 0) {
return SUCCESS;
}
switch (params.data[0]) {
case TEST_VERIFY_TRANSLATIONS: {
sol_log("verify data translations");

View File

@ -19,6 +19,7 @@ use solana_sdk::{
const TEST_SUCCESS: u8 = 1;
const TEST_PRIVILEGE_ESCALATION_SIGNER: u8 = 2;
const TEST_PRIVILEGE_ESCALATION_WRITABLE: u8 = 3;
const TEST_PPROGRAM_NOT_EXECUTABLE: u8 = 4;
// const MINT_INDEX: usize = 0;
const ARGUMENT_INDEX: usize = 1;
@ -192,10 +193,7 @@ fn process_instruction(
invoke(&invoked_instruction, accounts)?;
invoked_instruction.accounts[0].is_signer = true;
assert_eq!(
invoke(&invoked_instruction, accounts),
Err(ProgramError::Custom(0x0b9f_0002))
);
invoke(&invoked_instruction, accounts)?;
}
TEST_PRIVILEGE_ESCALATION_WRITABLE => {
info!("Test privilege escalation writable");
@ -207,10 +205,17 @@ fn process_instruction(
invoke(&invoked_instruction, accounts)?;
invoked_instruction.accounts[0].is_writable = true;
assert_eq!(
invoke(&invoked_instruction, accounts),
Err(ProgramError::Custom(0x0b9f_0002))
invoke(&invoked_instruction, accounts)?;
}
TEST_PPROGRAM_NOT_EXECUTABLE => {
info!("Test program not executable");
let instruction = create_instruction(
*accounts[ARGUMENT_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, true, true)],
vec![TEST_RETURN_ERROR],
);
invoke(&instruction, accounts)?;
}
_ => panic!(),
}

View File

@ -311,6 +311,7 @@ mod bpf {
const TEST_SUCCESS: u8 = 1;
const TEST_PRIVILEGE_ESCALATION_SIGNER: u8 = 2;
const TEST_PRIVILEGE_ESCALATION_WRITABLE: u8 = 3;
const TEST_PPROGRAM_NOT_EXECUTABLE: u8 = 4;
let mut programs = Vec::new();
#[cfg(feature = "bpf_c")]
@ -397,7 +398,7 @@ mod bpf {
let instruction = Instruction::new(
invoke_program_id,
&TEST_PRIVILEGE_ESCALATION_SIGNER,
&[TEST_PRIVILEGE_ESCALATION_SIGNER, nonce1, nonce2, nonce3],
account_metas.clone(),
);
let message = Message::new(&[instruction], Some(&mint_pubkey));
@ -419,7 +420,7 @@ mod bpf {
let instruction = Instruction::new(
invoke_program_id,
&TEST_PRIVILEGE_ESCALATION_WRITABLE,
&[TEST_PRIVILEGE_ESCALATION_WRITABLE, nonce1, nonce2, nonce3],
account_metas.clone(),
);
let message = Message::new(&[instruction], Some(&mint_pubkey));
@ -438,6 +439,28 @@ mod bpf {
.unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(194969602))
);
let instruction = Instruction::new(
invoke_program_id,
&[TEST_PPROGRAM_NOT_EXECUTABLE, nonce1, nonce2, nonce3],
account_metas.clone(),
);
let message = Message::new(&[instruction], Some(&mint_pubkey));
assert_eq!(
bank_client
.send_and_confirm_message(
&[
&mint_keypair,
&argument_keypair,
&invoked_argument_keypair,
&from_keypair
],
message,
)
.unwrap_err()
.unwrap(),
TransactionError::InstructionError(0, InstructionError::AccountNotExecutable)
);
}
}
}

View File

@ -823,6 +823,9 @@ fn call<'a>(
// Process instruction
let program_account = (*accounts[callee_program_id_index]).clone();
if !program_account.borrow().executable {
return Err(SyscallError::InstructionError(InstructionError::AccountNotExecutable).into());
}
let executable_accounts = vec![(callee_program_id, program_account)];
let mut message_processor = MessageProcessor::default();
for (program_id, process_instruction) in invoke_context.get_programs().iter() {

View File

@ -329,7 +329,6 @@ impl MessageProcessor {
})
.collect();
keyed_accounts.append(&mut keyed_accounts2);
assert!(keyed_accounts[0].executable()?, "account not executable");
Ok(keyed_accounts)
}