From 6f318822602385fb7fa09fe5fec558ca29231090 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 18 Aug 2021 18:07:36 +0000 Subject: [PATCH] Fix memoverlap check (backport #19232) (#19259) * Fix memoverlap check (#19232) (cherry picked from commit 9be988db41c03cc644417584fb9bbee75554da14) # Conflicts: # programs/bpf_loader/src/syscalls.rs # sdk/src/feature_set.rs * Resolve conflicts Co-authored-by: Jack May --- programs/bpf_loader/src/syscalls.rs | 32 ++++++++++++++++++++++++----- sdk/src/feature_set.rs | 10 +++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 6282291435..bbc507ec68 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -20,8 +20,9 @@ use solana_sdk::{ epoch_schedule::EpochSchedule, feature_set::{ cpi_data_cost, enforce_aligned_host_addrs, keccak256_syscall_enabled, - libsecp256k1_0_5_upgrade_enabled, memory_ops_syscalls, secp256k1_recover_syscall_enabled, - set_upgrade_authority_via_cpi_enabled, sysvar_via_syscall, update_data_on_realloc, + libsecp256k1_0_5_upgrade_enabled, mem_overlap_fix, memory_ops_syscalls, + secp256k1_recover_syscall_enabled, set_upgrade_authority_via_cpi_enabled, + sysvar_via_syscall, update_data_on_realloc, }, hash::{Hasher, HASH_BYTES}, ic_msg, @@ -295,6 +296,7 @@ pub fn bind_syscall_context_objects<'a>( cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit, compute_meter: invoke_context.get_compute_meter(), loader_id, + mem_overlap_fix: invoke_context.is_feature_active(&mem_overlap_fix::id()), }), ); bind_feature_gated_syscall_context_object!( @@ -1205,11 +1207,17 @@ impl<'a> SyscallObject for SyscallKeccak256<'a> { } } +fn check_overlapping(src_addr: u64, dst_addr: u64, n: u64) -> bool { + (src_addr <= dst_addr && src_addr + n > dst_addr) + || (dst_addr <= src_addr && dst_addr + n > src_addr) +} + /// memcpy pub struct SyscallMemcpy<'a> { cost: u64, compute_meter: Rc>, loader_id: &'a Pubkey, + mem_overlap_fix: bool, } impl<'a> SyscallObject for SyscallMemcpy<'a> { fn call( @@ -1222,8 +1230,11 @@ impl<'a> SyscallObject for SyscallMemcpy<'a> { memory_mapping: &MemoryMapping, result: &mut Result>, ) { - // cannot be overlapping - if dst_addr + n > src_addr && src_addr > dst_addr { + if if self.mem_overlap_fix { + check_overlapping(src_addr, dst_addr, n) + } else { + dst_addr + n > src_addr && src_addr > dst_addr + } { *result = Err(SyscallError::CopyOverlapping.into()); return; } @@ -1243,7 +1254,7 @@ impl<'a> SyscallObject for SyscallMemcpy<'a> { *result = Ok(0); } } -/// memcpy +/// memmove pub struct SyscallMemmove<'a> { cost: u64, compute_meter: Rc>, @@ -3377,4 +3388,15 @@ mod tests { assert_eq!(got_rent, src_rent); } } + + #[test] + fn test_overlapping() { + assert!(!check_overlapping(10, 7, 3)); + assert!(check_overlapping(10, 8, 3)); + assert!(check_overlapping(10, 9, 3)); + assert!(check_overlapping(10, 10, 3)); + assert!(check_overlapping(10, 11, 3)); + assert!(check_overlapping(10, 12, 3)); + assert!(!check_overlapping(10, 13, 3)); + } } diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index 6f2cd49f9e..9c7f484472 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -179,6 +179,14 @@ pub mod stake_merge_with_unmatched_credits_observed { solana_sdk::declare_id!("meRgp4ArRPhD3KtCY9c5yAf2med7mBLsjKTPeVUHqBL"); } +pub mod gate_large_block { + solana_sdk::declare_id!("2ry7ygxiYURULZCrypHhveanvP5tzZ4toRwVp89oCNSj"); +} + +pub mod mem_overlap_fix { + solana_sdk::declare_id!("vXDCFK7gphrEmyf5VnKgLmqbdJ4UxD2eZH1qbdouYKF"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -223,6 +231,8 @@ lazy_static! { (merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"), (spl_token_v2_set_authority_fix::id(), "spl-token set_authority fix"), (stake_merge_with_unmatched_credits_observed::id(), "allow merging active stakes with unmatched credits_observed #18985"), + (gate_large_block::id(), "validator checks block cost against max limit in realtime, reject if exceeds."), + (mem_overlap_fix::id(), "Memory overlap fix"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()