* Check that the program was granted access to program_id (#13890)
(cherry picked from commit 733fcbaa6c
)
# Conflicts:
# programs/bpf/Cargo.toml
# programs/bpf/tests/programs.rs
* Resolve conflicts
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
15
programs/bpf/Cargo.lock
generated
15
programs/bpf/Cargo.lock
generated
@ -738,9 +738,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",
|
||||
@ -1895,6 +1895,13 @@ dependencies = [
|
||||
"solana-program",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-caller-access"
|
||||
version = "1.4.14"
|
||||
dependencies = [
|
||||
"solana-program",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-custom-heap"
|
||||
version = "1.4.14"
|
||||
@ -2347,9 +2354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.1.33"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14a45ec96d6902676708f52d180229ea3933df93eadb3e96e356377d467831b6"
|
||||
checksum = "6b54ad0656df5f2c8acdd030ce769aaf49ee32995e569225bfb5121688863a09"
|
||||
dependencies = [
|
||||
"byteorder 1.3.4",
|
||||
"combine",
|
||||
|
@ -37,6 +37,8 @@ members = [
|
||||
"rust/128bit",
|
||||
"rust/128bit_dep",
|
||||
"rust/alloc",
|
||||
"rust/call_depth",
|
||||
"rust/caller_access",
|
||||
"rust/custom_heap",
|
||||
"rust/dep_crate",
|
||||
"rust/deprecated_loader",
|
||||
@ -58,7 +60,6 @@ members = [
|
||||
"rust/ristretto",
|
||||
"rust/sanity",
|
||||
"rust/sha256",
|
||||
"rust/call_depth",
|
||||
"rust/sysval",
|
||||
]
|
||||
|
||||
|
@ -61,6 +61,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
3407
programs/bpf/rust/caller_access/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
programs/bpf/rust/caller_access/Cargo.toml
Normal file
18
programs/bpf/rust/caller_access/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-caller-access"
|
||||
version = "1.4.14"
|
||||
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-program = { path = "../../../../sdk/program", version = "1.4.14" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
2
programs/bpf/rust/caller_access/Xargo.toml
Normal file
2
programs/bpf/rust/caller_access/Xargo.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[target.bpfel-unknown-unknown.dependencies.std]
|
||||
features = []
|
52
programs/bpf/rust/caller_access/src/lib.rs
Normal file
52
programs/bpf/rust/caller_access/src/lib.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use solana_program::{
|
||||
account_info::AccountInfo,
|
||||
entrypoint,
|
||||
entrypoint::ProgramResult,
|
||||
instruction::{AccountMeta, Instruction},
|
||||
msg,
|
||||
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,
|
||||
);
|
||||
msg!("{:?} 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)],
|
||||
);
|
||||
msg!("{:?} calling {:?}", program_id, program_id);
|
||||
invoke(&ix, accounts)?;
|
||||
}
|
||||
|
||||
_ => msg!("Should never get here"),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -704,6 +704,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(&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")]
|
||||
|
@ -1156,6 +1156,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(())
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user