From 7eb5db98cfcb0b539901bfae8bb53574c56cc68b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 30 Dec 2020 06:39:22 +0000 Subject: [PATCH] Limit CPI from calling loader or native programs (#14252) (#14319) (cherry picked from commit 0b479ab1800d161b046832602d205cec2ccc2c8b) Co-authored-by: Jack May --- programs/bpf/tests/programs.rs | 1 + programs/bpf_loader/src/syscalls.rs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index ce616718b2..b4fc450d08 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -1243,6 +1243,7 @@ fn test_program_bpf_test_use_latest_executor() { .is_ok()); } +#[ignore] // Invoking BPF loaders from CPI not allowed #[cfg(feature = "bpf_rust")] #[test] fn test_program_bpf_test_use_latest_executor2() { diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 39cdd49b87..7984db4894 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -12,7 +12,7 @@ use solana_sdk::{ account::Account, account_info::AccountInfo, account_utils::StateMut, - bpf_loader_deprecated, + bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS}, feature_set::{ @@ -23,6 +23,7 @@ use solana_sdk::{ instruction::{AccountMeta, Instruction, InstructionError}, keyed_account::KeyedAccount, message::Message, + native_loader, process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger}, program_error::ProgramError, pubkey::{Pubkey, PubkeyError, MAX_SEEDS}, @@ -1160,6 +1161,17 @@ impl<'a> SyscallObject for SyscallInvokeSignedC<'a> { } } +fn is_authorized_program(program_id: &Pubkey) -> Result<(), EbpfError> { + if native_loader::check_id(program_id) + || bpf_loader::check_id(program_id) + || bpf_loader_deprecated::check_id(program_id) + || bpf_loader_upgradeable::check_id(program_id) + { + return Err(SyscallError::InstructionError(InstructionError::UnsupportedProgramId).into()); + } + Ok(()) +} + /// Call process instruction, common to both Rust and C fn call<'a>( syscall: &mut dyn SyscallInvokeSigned<'a>, @@ -1195,6 +1207,7 @@ fn call<'a>( let (message, callee_program_id) = MessageProcessor::create_message(&instruction, &keyed_account_refs, &signers) .map_err(SyscallError::InstructionError)?; + is_authorized_program(&callee_program_id)?; let (accounts, account_refs) = syscall.translate_accounts( &message, account_infos_addr,