Check that the program was granted access to program_id (bp #13890) (#13892)

* Check that the program was granted access to program_id (#13890)

(cherry picked from commit 733fcbaa6c)

# Conflicts:
#	programs/bpf/tests/programs.rs

* Resolve conflicts

* nudge

* nudge

Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
mergify[bot]
2020-12-01 18:42:34 +00:00
committed by GitHub
parent 3318772bfe
commit f1265b544c
9 changed files with 3548 additions and 9 deletions

View File

@ -703,9 +703,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "goblin"
version = "0.2.3"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884"
checksum = "c69552f48b18aa6102ce0c82dd9bc9d3f8af5fc0a5797069b1b466b90570e39c"
dependencies = [
"log",
"plain",
@ -1812,6 +1812,13 @@ dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-caller-access"
version = "1.3.24"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-custom-heap"
version = "1.3.24"
@ -2187,9 +2194,9 @@ dependencies = [
[[package]]
name = "solana_rbpf"
version = "0.1.32"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a95dbe2b00920ac4e1524b7442cf5319f01e8fa5742930ac60148882fd7738b"
checksum = "6b54ad0656df5f2c8acdd030ce769aaf49ee32995e569225bfb5121688863a09"
dependencies = [
"byteorder 1.3.4",
"combine",

View File

@ -38,6 +38,7 @@ members = [
"rust/128bit_dep",
"rust/alloc",
"rust/call_depth",
"rust/caller_access",
"rust/custom_heap",
"rust/dep_crate",
"rust/deprecated_loader",

View File

@ -68,6 +68,7 @@ fn main() {
"128bit",
"alloc",
"call_depth",
"caller_access",
"custom_heap",
"dep_crate",
"deprecated_loader",

3407
programs/bpf/rust/caller_access/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
[package]
name = "solana-bpf-rust-caller-access"
version = "1.3.24"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.3.24", default-features = false }
[features]
program = ["solana-sdk/program"]
default = ["program", "solana-sdk/default"]
[lib]
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -0,0 +1,52 @@
use solana_sdk::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
info,
instruction::{AccountMeta, Instruction},
program::invoke,
pubkey::Pubkey,
};
use std::convert::TryInto;
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
if instruction_data.len() == 32 {
let key = Pubkey::new_from_array(instruction_data.try_into().unwrap());
let ix = Instruction::new(key, &[2], vec![]);
let mut lamports = accounts[0].lamports();
let owner = &accounts[0].owner;
let mut data = accounts[0].try_borrow_mut_data()?;
let account = AccountInfo::new(
&key,
false,
false,
&mut lamports,
&mut data,
&owner,
true,
0,
);
info!(&format!("{:?} calling {:?}", program_id, key));
invoke(&ix, &[account])?;
} else {
match instruction_data[0] {
1 => {
let ix = Instruction::new(
*program_id,
&accounts[1].key.to_bytes(),
vec![AccountMeta::new_readonly(*program_id, false)],
);
info!(&format!("{:?} calling {:?}", program_id, program_id));
invoke(&ix, accounts)?;
}
_ => info!("Should never get here"),
}
}
Ok(())
}

View File

@ -523,11 +523,7 @@ fn test_program_bpf_invoke() {
&[TEST_SUCCESS, bump_seed1, bump_seed2, bump_seed3],
account_metas.clone(),
);
let noop_instruction = Instruction::new(
noop_program_id,
&(),
vec![]
);
let noop_instruction = Instruction::new(noop_program_id, &(), vec![]);
let message = Message::new(&[instruction, noop_instruction], Some(&mint_pubkey));
let tx = Transaction::new(
&[
@ -699,6 +695,43 @@ fn test_program_bpf_invoke() {
assert_eq!(i as u8, account.data[i]);
}
}
// Check the caller has access to cpi program
{
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_genesis_config(50);
let mut bank = Bank::new(&genesis_config);
let (name, id, entrypoint) = solana_bpf_loader_program!();
bank.add_builtin_loader(&name, id, entrypoint);
let bank = Arc::new(bank);
let bank_client = BankClient::new_shared(&bank);
let caller_pubkey = load_bpf_program(
&bank_client,
&bpf_loader::id(),
&mint_keypair,
"solana_bpf_rust_caller_access",
);
let caller2_pubkey = load_bpf_program(
&bank_client,
&bpf_loader::id(),
&mint_keypair,
"solana_bpf_rust_caller_access",
);
let account_metas = vec![
AccountMeta::new_readonly(caller_pubkey, false),
AccountMeta::new_readonly(caller2_pubkey, false),
];
let instruction = Instruction::new(caller_pubkey, &[1_u8], account_metas.clone());
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::MissingAccount)
);
}
}
#[cfg(feature = "bpf_rust")]

View File

@ -1036,6 +1036,20 @@ fn verify_instruction<'a>(
}
}
// validate the caller has access to the program account
let _ = callers_keyed_accounts
.iter()
.find_map(|keyed_account| {
if &instruction.program_id == keyed_account.unsigned_key() {
Some(keyed_account)
} else {
None
}
})
.ok_or(SyscallError::InstructionError(
InstructionError::MissingAccount,
))?;
Ok(())
}