Add program id spoof tests (#13866)

This commit is contained in:
Jack May 2020-11-30 13:06:11 -08:00 committed by GitHub
parent 6cf6cd2fba
commit b47bd0a296
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 7036 additions and 33 deletions

View File

@ -63,9 +63,9 @@ checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e"
[[package]]
name = "assert_matches"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
checksum = "695579f0f2520f3774bb40461e5adb066459d4e0af4d59d20175484fb8e9edf1"
[[package]]
name = "atty"
@ -91,7 +91,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
dependencies = [
"addr2line",
"cfg-if",
"cfg-if 0.1.10",
"libc",
"object",
"rustc-demangle",
@ -129,7 +129,7 @@ dependencies = [
"arrayref",
"arrayvec",
"cc",
"cfg-if",
"cfg-if 0.1.10",
"constant_time_eq",
"crypto-mac 0.8.0",
"digest 0.9.0",
@ -267,15 +267,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chrono"
version = "0.4.11"
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"serde",
"time",
"winapi 0.3.8",
]
[[package]]
@ -332,7 +340,7 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -363,7 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg",
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils",
"lazy_static",
"maybe-uninit",
@ -377,7 +385,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils",
"maybe-uninit",
]
@ -389,7 +397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"cfg-if 0.1.10",
"lazy_static",
]
@ -452,7 +460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f260e2fc850179ef410018660006951c1b55b79e8087e87111a2c388994b9b5"
dependencies = [
"ahash",
"cfg-if",
"cfg-if 0.1.10",
"num_cpus",
]
@ -534,7 +542,7 @@ version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -568,7 +576,7 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"redox_syscall",
"winapi 0.3.8",
@ -580,7 +588,7 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"crc32fast",
"libc",
"miniz_oxide",
@ -622,9 +630,9 @@ checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
[[package]]
name = "futures-channel"
version = "0.3.5"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151"
dependencies = [
"futures-core",
]
@ -655,9 +663,9 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.5"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
[[package]]
name = "futures-task"
@ -722,7 +730,7 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"wasi",
]
@ -1067,7 +1075,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -1138,7 +1146,7 @@ version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
@ -1180,7 +1188,7 @@ version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"winapi 0.3.8",
]
@ -1299,7 +1307,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"cloudabi",
"libc",
"redox_syscall",
@ -1838,11 +1846,11 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]]
name = "socket2"
version = "0.3.15"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"winapi 0.3.8",
@ -2066,6 +2074,20 @@ dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-spoof1"
version = "1.5.0"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-spoof1-system"
version = "1.5.0"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.5.0"
@ -2458,7 +2480,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"rand",
"redox_syscall",
@ -2752,7 +2774,7 @@ version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"log",
"pin-project-lite",
"tracing-core",
@ -2889,7 +2911,7 @@ version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"serde",
"serde_json",
"wasm-bindgen-macro",
@ -2916,7 +2938,7 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64487204d863f109eb77e8462189d111f27cb5712cc9fdb3461297a76963a2f6"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"js-sys",
"wasm-bindgen",
"web-sys",

View File

@ -37,6 +37,7 @@ members = [
"rust/128bit",
"rust/128bit_dep",
"rust/alloc",
"rust/call_depth",
"rust/custom_heap",
"rust/dep_crate",
"rust/deprecated_loader",
@ -58,7 +59,8 @@ members = [
"rust/ristretto",
"rust/sanity",
"rust/sha256",
"rust/call_depth",
"rust/spoof1",
"rust/spoof1_system",
"rust/sysval",
]

View File

@ -80,7 +80,8 @@ fn main() {
"ristretto",
"sanity",
"sha256",
"call_depth",
"spoof1",
"spoof1_system",
"sysval",
];
for program in rust_programs.iter() {

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
[package]
name = "solana-bpf-rust-spoof1"
version = "1.5.0"
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.5.0" }
[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,54 @@
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
info,
instruction::{AccountMeta, Instruction},
program::invoke,
pubkey::Pubkey,
system_instruction::SystemInstruction,
system_program,
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let fake_system = &accounts[1];
let target = &accounts[2];
let me = &accounts[3];
let mut tmp_native_owner = [0u8; 32];
tmp_native_owner.copy_from_slice(accounts[0].owner.as_ref());
let owner_addr = accounts[0].owner as *const Pubkey;
unsafe {
std::ptr::write_volatile(owner_addr as *mut [u8; 32], fake_system.owner.to_bytes());
}
let system = &accounts[0];
let mut new_system = system.clone();
new_system.data = fake_system.data.clone();
let account_metas = vec![
AccountMeta::new(*target.key, false),
AccountMeta::new(*me.key, false),
];
let ix = Instruction::new(
system_program::id(),
&SystemInstruction::Transfer { lamports: 1 },
account_metas,
);
info!("swapped owner and data");
invoke(&ix, &[target.clone(), me.clone(), new_system])?;
let owner_addr = accounts[0].owner as *const Pubkey;
unsafe {
std::ptr::write_volatile(owner_addr as *mut [u8; 32], tmp_native_owner);
}
Ok(())
}

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
[package]
name = "solana-bpf-rust-spoof1-system"
version = "1.5.0"
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.5.0" }
[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,19 @@
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, pubkey::Pubkey,
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let from = &accounts[0];
let to = &accounts[1];
let to_balance = to.lamports();
**to.lamports.borrow_mut() = to_balance + from.lamports();
**from.lamports.borrow_mut() = 0u64;
Ok(())
}

View File

@ -745,6 +745,57 @@ fn test_program_bpf_invoke() {
assert_eq!(i as u8, account.data[i]);
}
}
// Check for program id spoofing
{
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 malicious_swap_pubkey = load_bpf_program(
&bank_client,
&bpf_loader::id(),
&mint_keypair,
"solana_bpf_rust_spoof1",
);
let malicious_system_pubkey = load_bpf_program(
&bank_client,
&bpf_loader::id(),
&mint_keypair,
"solana_bpf_rust_spoof1_system",
);
let from_pubkey = Pubkey::new_unique();
let account = Account::new(10, 0, &solana_sdk::system_program::id());
bank.store_account(&from_pubkey, &account);
let to_pubkey = Pubkey::new_unique();
let account = Account::new(0, 0, &solana_sdk::system_program::id());
bank.store_account(&to_pubkey, &account);
let account_metas = vec![
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
AccountMeta::new_readonly(malicious_system_pubkey, false),
AccountMeta::new(from_pubkey, false),
AccountMeta::new(to_pubkey, false),
];
let instruction = Instruction::new(malicious_swap_pubkey, &(), account_metas.clone());
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::ModifiedProgramId)
);
assert_eq!(10, bank.get_balance(&from_pubkey));
assert_eq!(0, bank.get_balance(&to_pubkey));
}
}
#[cfg(feature = "bpf_rust")]