From f705340971298534e1edb952675943ef857d65cf Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 3 Dec 2020 09:52:08 -0800 Subject: [PATCH] Invoke with empty account slice (bp #13931) (#13940) * Invoke with empty account slice (#13931) (cherry picked from commit 1c51711c7580e200ee7172947651dd6ae3e65b2f) * nudge ci Co-authored-by: Jack May --- programs/bpf/Cargo.lock | 90 ++++++++++++++--------------- programs/bpf/c/src/invoke/invoke.c | 12 ++++ programs/bpf/rust/invoke/src/lib.rs | 6 ++ programs/bpf/tests/programs.rs | 33 +++++++++++ programs/bpf_loader/src/syscalls.rs | 2 +- 5 files changed, 97 insertions(+), 46 deletions(-) diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 248de7dd5b..cb1ae07d33 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -1837,7 +1837,7 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "byteorder 1.3.4", @@ -1852,7 +1852,7 @@ dependencies = [ [[package]] name = "solana-bpf-programs" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "byteorder 1.3.4", @@ -1868,7 +1868,7 @@ dependencies = [ [[package]] name = "solana-bpf-rust-128bit" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-bpf-rust-128bit-dep", "solana-program", @@ -1876,42 +1876,42 @@ dependencies = [ [[package]] name = "solana-bpf-rust-128bit-dep" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-alloc" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-call-depth" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-caller-access" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-custom-heap" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-dep-crate" -version = "1.4.14" +version = "1.4.15" dependencies = [ "byteorder 1.3.4", "solana-program", @@ -1919,21 +1919,21 @@ dependencies = [ [[package]] name = "solana-bpf-rust-deprecated_loader" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-dup-accounts" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-error-handling" -version = "1.4.14" +version = "1.4.15" dependencies = [ "num-derive 0.2.5", "num-traits", @@ -1943,21 +1943,21 @@ dependencies = [ [[package]] name = "solana-bpf-rust-external-spend" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-instruction-introspection" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-invoke" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-bpf-rust-invoked", "solana-program", @@ -1965,21 +1965,21 @@ dependencies = [ [[package]] name = "solana-bpf-rust-invoked" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-iter" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-many-args" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-bpf-rust-many-args-dep", "solana-program", @@ -1987,35 +1987,35 @@ dependencies = [ [[package]] name = "solana-bpf-rust-many-args-dep" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-mem" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-noop" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-panic" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-param-passing" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-bpf-rust-param-passing-dep", "solana-program", @@ -2023,14 +2023,14 @@ dependencies = [ [[package]] name = "solana-bpf-rust-param-passing-dep" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-rand" -version = "1.4.14" +version = "1.4.15" dependencies = [ "getrandom", "rand", @@ -2039,7 +2039,7 @@ dependencies = [ [[package]] name = "solana-bpf-rust-ristretto" -version = "1.4.14" +version = "1.4.15" dependencies = [ "curve25519-dalek 3.0.0", "getrandom", @@ -2048,35 +2048,35 @@ dependencies = [ [[package]] name = "solana-bpf-rust-ro-modify" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-sanity" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-sha256" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-bpf-rust-sysval" -version = "1.4.14" +version = "1.4.15" dependencies = [ "solana-program", ] [[package]] name = "solana-config-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "chrono", @@ -2088,7 +2088,7 @@ dependencies = [ [[package]] name = "solana-crate-features" -version = "1.4.14" +version = "1.4.15" dependencies = [ "backtrace", "bytes 0.4.12", @@ -2110,7 +2110,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bs58", "bv", @@ -2128,7 +2128,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.4.14" +version = "1.4.15" dependencies = [ "lazy_static", "proc-macro2 1.0.24", @@ -2139,7 +2139,7 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.4.14" +version = "1.4.15" dependencies = [ "env_logger", "lazy_static", @@ -2148,7 +2148,7 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.4.14" +version = "1.4.15" dependencies = [ "jemalloc-ctl", "jemallocator", @@ -2159,7 +2159,7 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.4.14" +version = "1.4.15" dependencies = [ "env_logger", "gethostname", @@ -2171,7 +2171,7 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "bs58", @@ -2199,7 +2199,7 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.4.14" +version = "1.4.15" dependencies = [ "lazy_static", "num_cpus", @@ -2207,7 +2207,7 @@ dependencies = [ [[package]] name = "solana-runtime" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "blake3", @@ -2256,7 +2256,7 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.4.14" +version = "1.4.15" dependencies = [ "assert_matches", "bincode", @@ -2298,7 +2298,7 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bs58", "proc-macro2 1.0.24", @@ -2309,7 +2309,7 @@ dependencies = [ [[package]] name = "solana-secp256k1-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "digest 0.9.0", @@ -2322,7 +2322,7 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "log", @@ -2342,7 +2342,7 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.4.14" +version = "1.4.15" dependencies = [ "bincode", "log", diff --git a/programs/bpf/c/src/invoke/invoke.c b/programs/bpf/c/src/invoke/invoke.c index 82e168242e..0bded4aaac 100644 --- a/programs/bpf/c/src/invoke/invoke.c +++ b/programs/bpf/c/src/invoke/invoke.c @@ -8,6 +8,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 uint8_t TEST_EMPTY_ACCOUNTS_SLICE = 5; static const int MINT_INDEX = 0; static const int ARGUMENT_INDEX = 1; @@ -270,6 +271,17 @@ extern uint64_t entrypoint(const uint8_t *input) { SOL_ARRAY_SIZE(data)}; return sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)); } + case TEST_EMPTY_ACCOUNTS_SLICE: { + sol_log("Empty accounts slice "); + + SolAccountMeta arguments[] = {}; + uint8_t data[] = {}; + const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key, + arguments, SOL_ARRAY_SIZE(arguments), + data, SOL_ARRAY_SIZE(data)}; + + sol_assert(SUCCESS == sol_invoke(&instruction, 0, 0)); + } default: sol_panic(); } diff --git a/programs/bpf/rust/invoke/src/lib.rs b/programs/bpf/rust/invoke/src/lib.rs index 4d3f19885f..901e390618 100644 --- a/programs/bpf/rust/invoke/src/lib.rs +++ b/programs/bpf/rust/invoke/src/lib.rs @@ -20,6 +20,7 @@ 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 TEST_EMPTY_ACCOUNTS_SLICE: u8 = 5; // const MINT_INDEX: usize = 0; const ARGUMENT_INDEX: usize = 1; @@ -356,6 +357,11 @@ fn process_instruction( ); invoke(&instruction, accounts)?; } + TEST_EMPTY_ACCOUNTS_SLICE => { + msg!("Empty accounts slice"); + let instruction = create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![]); + invoke(&instruction, &[])?; + } _ => panic!(), } diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 4c9e992f0b..b4d68efcd3 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -445,6 +445,7 @@ fn test_program_bpf_invoke() { const TEST_PRIVILEGE_ESCALATION_SIGNER: u8 = 2; const TEST_PRIVILEGE_ESCALATION_WRITABLE: u8 = 3; const TEST_PPROGRAM_NOT_EXECUTABLE: u8 = 4; + const TEST_EMPTY_ACCOUNTS_SLICE: u8 = 5; #[allow(dead_code)] #[derive(Debug)] @@ -687,6 +688,38 @@ fn test_program_bpf_invoke() { TransactionError::InstructionError(0, InstructionError::AccountNotExecutable) ); + let instruction = Instruction::new( + invoke_program_id, + &[ + TEST_EMPTY_ACCOUNTS_SLICE, + bump_seed1, + bump_seed2, + bump_seed3, + ], + account_metas.clone(), + ); + let message = Message::new(&[instruction], Some(&mint_pubkey)); + let tx = Transaction::new( + &[ + &mint_keypair, + &argument_keypair, + &invoked_argument_keypair, + &from_keypair, + ], + message.clone(), + bank.last_blockhash(), + ); + let (result, inner_instructions) = process_transaction_and_record_inner(&bank, tx); + let invoked_programs: Vec = inner_instructions[0] + .iter() + .map(|ix| message.account_keys[ix.program_id_index as usize].clone()) + .collect(); + assert_eq!(invoked_programs, vec![]); + assert_eq!( + result.unwrap_err(), + TransactionError::InstructionError(0, InstructionError::MissingAccount) + ); + // Check final state assert_eq!(43, bank.get_balance(&derived_key1)); diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index b52d6a665b..14e577ec2e 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -1004,7 +1004,6 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> { ro_regions, self.loader_id )?; - let first_info_addr = &account_infos[0] as *const _ as u64; let mut accounts = Vec::with_capacity(message.account_keys.len()); let mut refs = Vec::with_capacity(message.account_keys.len()); 'root: for account_key in message.account_keys.iter() { @@ -1032,6 +1031,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> { self.loader_id )?; + let first_info_addr = &account_infos[0] as *const _ as u64; let addr = &account_info.data_len as *const u64 as u64; let vm_addr = account_infos_addr + (addr - first_info_addr); let _ =