Skip to content

Commit

Permalink
cpi: direct_mapping: error out if ref_to_len_in_vm points to account …
Browse files Browse the repository at this point in the history
…memory

If ref_to_len_in_vm is allowed to be in account memory, calles could mutate it,
essentially letting callees directly mutate callers memory.
  • Loading branch information
alessandrod committed Aug 24, 2023
1 parent 3ccbb65 commit ea33b5c
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use {
crate::{declare_syscall, serialization::account_data_region_memory_state},
scopeguard::defer,
solana_program_runtime::invoke_context::SerializedAccountMetadata,
solana_rbpf::memory_region::{MemoryRegion, MemoryState},
solana_rbpf::{
ebpf,
memory_region::{MemoryRegion, MemoryState},
},
solana_sdk::{
feature_set::enable_bpf_loader_set_authority_checked_ix,
stable_layout::stable_instruction::StableInstruction,
Expand Down Expand Up @@ -174,9 +177,17 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
)?;

let ref_to_len_in_vm = if direct_mapping {
let vm_addr = (account_info.data.as_ptr() as *const u64 as u64)
.saturating_add(size_of::<u64>() as u64);
// In the same vein as the other check_account_info_pointer()
// checks, we don't lock this pointer to a specific address but we
// don't want it to be inside accounts, or calles might be able to
// write to the pointed memory.
if vm_addr >= ebpf::MM_INPUT_START {
return Err(SyscallError::InvalidPointer.into());
}
VmValue::VmAddress {
vm_addr: (account_info.data.as_ptr() as *const u64 as u64)
.saturating_add(size_of::<u64>() as u64),
vm_addr,
memory_mapping,
check_aligned: invoke_context.get_check_aligned(),
}
Expand Down Expand Up @@ -335,6 +346,13 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
.saturating_sub(account_info as *const _ as *const u64 as u64);

let ref_to_len_in_vm = if direct_mapping {
// In the same vein as the other check_account_info_pointer()
// checks, we don't lock this pointer to a specific address but we
// don't want it to be inside accounts, or calles might be able to
// write to the pointed memory.
if data_len_vm_addr >= ebpf::MM_INPUT_START {
return Err(SyscallError::InvalidPointer.into());
}
VmValue::VmAddress {
vm_addr: data_len_vm_addr,
memory_mapping,
Expand Down

0 comments on commit ea33b5c

Please sign in to comment.