* Fix memoverlap check (#19232)
(cherry picked from commit 9be988db41
)
# Conflicts:
# programs/bpf_loader/src/syscalls.rs
# sdk/src/feature_set.rs
* Resolve conflicts
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@@ -20,8 +20,9 @@ use solana_sdk::{
|
|||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
feature_set::{
|
feature_set::{
|
||||||
cpi_data_cost, enforce_aligned_host_addrs, keccak256_syscall_enabled,
|
cpi_data_cost, enforce_aligned_host_addrs, keccak256_syscall_enabled,
|
||||||
libsecp256k1_0_5_upgrade_enabled, memory_ops_syscalls, secp256k1_recover_syscall_enabled,
|
libsecp256k1_0_5_upgrade_enabled, mem_overlap_fix, memory_ops_syscalls,
|
||||||
set_upgrade_authority_via_cpi_enabled, sysvar_via_syscall, update_data_on_realloc,
|
secp256k1_recover_syscall_enabled, set_upgrade_authority_via_cpi_enabled,
|
||||||
|
sysvar_via_syscall, update_data_on_realloc,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
ic_msg,
|
ic_msg,
|
||||||
@@ -295,6 +296,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||||||
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||||
compute_meter: invoke_context.get_compute_meter(),
|
compute_meter: invoke_context.get_compute_meter(),
|
||||||
loader_id,
|
loader_id,
|
||||||
|
mem_overlap_fix: invoke_context.is_feature_active(&mem_overlap_fix::id()),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
bind_feature_gated_syscall_context_object!(
|
bind_feature_gated_syscall_context_object!(
|
||||||
@@ -1205,11 +1207,17 @@ impl<'a> SyscallObject<BpfError> 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
|
/// memcpy
|
||||||
pub struct SyscallMemcpy<'a> {
|
pub struct SyscallMemcpy<'a> {
|
||||||
cost: u64,
|
cost: u64,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
loader_id: &'a Pubkey,
|
loader_id: &'a Pubkey,
|
||||||
|
mem_overlap_fix: bool,
|
||||||
}
|
}
|
||||||
impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
|
impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
|
||||||
fn call(
|
fn call(
|
||||||
@@ -1222,8 +1230,11 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
|
|||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
result: &mut Result<u64, EbpfError<BpfError>>,
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
||||||
) {
|
) {
|
||||||
// cannot be overlapping
|
if if self.mem_overlap_fix {
|
||||||
if dst_addr + n > src_addr && src_addr > dst_addr {
|
check_overlapping(src_addr, dst_addr, n)
|
||||||
|
} else {
|
||||||
|
dst_addr + n > src_addr && src_addr > dst_addr
|
||||||
|
} {
|
||||||
*result = Err(SyscallError::CopyOverlapping.into());
|
*result = Err(SyscallError::CopyOverlapping.into());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1243,7 +1254,7 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
|
|||||||
*result = Ok(0);
|
*result = Ok(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// memcpy
|
/// memmove
|
||||||
pub struct SyscallMemmove<'a> {
|
pub struct SyscallMemmove<'a> {
|
||||||
cost: u64,
|
cost: u64,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
@@ -3377,4 +3388,15 @@ mod tests {
|
|||||||
assert_eq!(got_rent, src_rent);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -179,6 +179,14 @@ pub mod stake_merge_with_unmatched_credits_observed {
|
|||||||
solana_sdk::declare_id!("meRgp4ArRPhD3KtCY9c5yAf2med7mBLsjKTPeVUHqBL");
|
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! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@@ -223,6 +231,8 @@ lazy_static! {
|
|||||||
(merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"),
|
(merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"),
|
||||||
(spl_token_v2_set_authority_fix::id(), "spl-token set_authority fix"),
|
(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"),
|
(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 ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user