diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 73d6711876..4a944d6475 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -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", diff --git a/programs/bpf/c/src/invoke/invoke.c b/programs/bpf/c/src/invoke/invoke.c index b097c153f2..ea80845eb0 100644 --- a/programs/bpf/c/src/invoke/invoke.c +++ b/programs/bpf/c/src/invoke/invoke.c @@ -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(); } diff --git a/programs/bpf/c/src/invoked/invoked.c b/programs/bpf/c/src/invoked/invoked.c index 3e72256a60..da805dccf3 100644 --- a/programs/bpf/c/src/invoked/invoked.c +++ b/programs/bpf/c/src/invoked/invoked.c @@ -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"); diff --git a/programs/bpf/rust/invoke/src/lib.rs b/programs/bpf/rust/invoke/src/lib.rs index 9c87f583e3..feee567c8c 100644 --- a/programs/bpf/rust/invoke/src/lib.rs +++ b/programs/bpf/rust/invoke/src/lib.rs @@ -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!(), } diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 0c1f0ece61..58f086264e 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -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) + ); } } } diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index b2adc123ef..38f78e9ae2 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -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() { diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 3f90e4dbef..57b5436723 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -329,7 +329,6 @@ impl MessageProcessor { }) .collect(); keyed_accounts.append(&mut keyed_accounts2); - assert!(keyed_accounts[0].executable()?, "account not executable"); Ok(keyed_accounts) }