From ead8cc436605ef60b93fb12771ac4d47f77274cb Mon Sep 17 00:00:00 2001 From: Jack May Date: Thu, 10 Mar 2022 11:48:09 -0800 Subject: [PATCH] Check for physical region overlap (#23568) --- programs/bpf_loader/src/syscalls.rs | 34 ++++++++++++++++++++--------- sdk/src/feature_set.rs | 9 ++++++-- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 36869d41dd..ba866c38f8 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -23,10 +23,11 @@ use { entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS}, feature_set::{ self, add_get_processed_sibling_instruction_syscall, blake3_syscall_enabled, - disable_fees_sysvar, do_support_realloc, fixed_memcpy_nonoverlapping_check, - libsecp256k1_0_5_upgrade_enabled, prevent_calling_precompiles_as_programs, - return_data_syscall_enabled, secp256k1_recover_syscall_enabled, - sol_log_data_syscall_enabled, syscall_saturated_math, update_syscall_base_costs, + check_physical_overlapping, disable_fees_sysvar, do_support_realloc, + fixed_memcpy_nonoverlapping_check, libsecp256k1_0_5_upgrade_enabled, + prevent_calling_precompiles_as_programs, return_data_syscall_enabled, + secp256k1_recover_syscall_enabled, sol_log_data_syscall_enabled, + syscall_saturated_math, update_syscall_base_costs, }, hash::{Hasher, HASH_BYTES}, instruction::{ @@ -1431,6 +1432,9 @@ impl<'a, 'b> SyscallObject for SyscallMemcpy<'a, 'b> { let use_fixed_nonoverlapping_check = invoke_context .feature_set .is_active(&fixed_memcpy_nonoverlapping_check::id()); + let do_check_physical_overlapping = invoke_context + .feature_set + .is_active(&check_physical_overlapping::id()); #[allow(clippy::collapsible_else_if)] if use_fixed_nonoverlapping_check { @@ -1451,16 +1455,26 @@ impl<'a, 'b> SyscallObject for SyscallMemcpy<'a, 'b> { }; let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result); - let dst = question_mark!( + let dst_ptr = question_mark!( translate_slice_mut::(memory_mapping, dst_addr, n, loader_id), result - ); - let src = question_mark!( + ) + .as_mut_ptr(); + let src_ptr = question_mark!( translate_slice::(memory_mapping, src_addr, n, loader_id), result - ); - unsafe { - std::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), n as usize); + ) + .as_ptr(); + if do_check_physical_overlapping + && !is_nonoverlapping(src_ptr as usize, dst_ptr as usize, n as usize) + { + unsafe { + std::ptr::copy(src_ptr, dst_ptr, n as usize); + } + } else { + unsafe { + std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, n as usize); + } } *result = Ok(0); } diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index c3a304cd89..519cdda824 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -319,6 +319,10 @@ pub mod syscall_saturated_math { solana_sdk::declare_id!("HyrbKftCdJ5CrUfEti6x26Cj7rZLNe32weugk7tLcWb8"); } +pub mod check_physical_overlapping { + solana_sdk::declare_id!("nWBqjr3gpETbiaVj3CBJ3HFC5TMdnJDGt21hnvSTvVZ"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -383,7 +387,7 @@ lazy_static! { (max_tx_account_locks::id(), "enforce max number of locked accounts per transaction"), (require_rent_exempt_accounts::id(), "require all new transaction accounts with data to be rent-exempt"), (filter_votes_outside_slot_hashes::id(), "filter vote slots older than the slot hashes history"), - (update_syscall_base_costs::id(), "Update syscall base costs"), + (update_syscall_base_costs::id(), "update syscall base costs"), (vote_withdraw_authority_may_change_authorized_voter::id(), "vote account withdraw authority may change the authorized voter #22521"), (spl_associated_token_account_v1_0_4::id(), "SPL Associated Token Account Program release version 1.0.4, tied to token 3.3.0 #22648"), (reject_vote_account_close_unless_zero_credit_epoch::id(), "fail vote account withdraw to 0 unless account earned 0 credits in last completed epoch"), @@ -392,7 +396,8 @@ lazy_static! { (disable_bpf_deprecated_load_instructions::id(), "disable ldabs* and ldind* BPF instructions"), (disable_bpf_unresolved_symbols_at_runtime::id(), "disable reporting of unresolved BPF symbols at runtime"), (record_instruction_in_transaction_context_push::id(), "move the CPI stack overflow check to the end of push"), - (syscall_saturated_math::id(), "Syscalls use saturated math"), + (syscall_saturated_math::id(), "syscalls use saturated math"), + (check_physical_overlapping::id(), "check physical overlapping regions"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()