use saturating arithmetic (#23435)
This commit is contained in:
parent
8184f755ae
commit
e9912744ef
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
use {
|
||||
crate::alloc,
|
||||
alloc::{Alloc, AllocErr},
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
pub mod alloc;
|
||||
pub mod allocator_bump;
|
||||
pub mod deprecated;
|
||||
|
@ -192,16 +191,17 @@ fn write_program_data<'a>(
|
|||
log_collector: Option<Rc<RefCell<LogCollector>>>,
|
||||
) -> Result<(), InstructionError> {
|
||||
let data = program.get_data_mut();
|
||||
if data.len() < program_data_offset + bytes.len() {
|
||||
let write_offset = program_data_offset.saturating_add(bytes.len());
|
||||
if data.len() < write_offset {
|
||||
ic_logger_msg!(
|
||||
log_collector,
|
||||
"Write overflow: {} < {}",
|
||||
data.len(),
|
||||
program_data_offset + bytes.len()
|
||||
write_offset
|
||||
);
|
||||
return Err(InstructionError::AccountDataTooSmall);
|
||||
}
|
||||
data[program_data_offset..program_data_offset + bytes.len()].copy_from_slice(bytes);
|
||||
data[program_data_offset..write_offset].copy_from_slice(bytes);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -224,10 +224,11 @@ pub fn create_vm<'a, 'b>(
|
|||
.feature_set
|
||||
.is_active(&requestable_heap_size::id())
|
||||
{
|
||||
let _ = invoke_context
|
||||
.get_compute_meter()
|
||||
.borrow_mut()
|
||||
.consume((heap_size as u64 / (32 * 1024)).saturating_sub(1) * compute_budget.heap_cost);
|
||||
let _ = invoke_context.get_compute_meter().borrow_mut().consume(
|
||||
((heap_size as u64).saturating_div(32_u64.saturating_mul(1024)))
|
||||
.saturating_sub(1)
|
||||
.saturating_mul(compute_budget.heap_cost),
|
||||
);
|
||||
}
|
||||
let mut heap =
|
||||
AlignedMemory::new_with_size(compute_budget.heap_size.unwrap_or(HEAP_LENGTH), HOST_ALIGN);
|
||||
|
@ -276,7 +277,7 @@ fn process_instruction_common(
|
|||
instruction_context.get_index_in_transaction(first_instruction_account)?,
|
||||
)?;
|
||||
let second_account_key = instruction_context
|
||||
.get_index_in_transaction(first_instruction_account + 1)
|
||||
.get_index_in_transaction(first_instruction_account.saturating_add(1))
|
||||
.and_then(|index_in_transaction| {
|
||||
transaction_context.get_key_of_account_at_index(index_in_transaction)
|
||||
});
|
||||
|
@ -287,7 +288,7 @@ fn process_instruction_common(
|
|||
.map(|key| key == program_id)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
first_instruction_account + 1
|
||||
first_instruction_account.saturating_add(1)
|
||||
} else {
|
||||
if instruction_context
|
||||
.try_borrow_account(transaction_context, first_instruction_account)?
|
||||
|
@ -302,9 +303,11 @@ fn process_instruction_common(
|
|||
let program =
|
||||
instruction_context.try_borrow_account(transaction_context, program_account_index)?;
|
||||
if program.is_executable() {
|
||||
// First instruction account can only be zero if called from CPI, which
|
||||
// means stack height better be greater than one
|
||||
debug_assert_eq!(
|
||||
first_instruction_account,
|
||||
1 - (invoke_context.get_stack_height() > 1) as usize,
|
||||
first_instruction_account == 0,
|
||||
invoke_context.get_stack_height() > 1
|
||||
);
|
||||
|
||||
if !check_loader_id(program.get_owner()) {
|
||||
|
@ -507,8 +510,9 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::Write::Authority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(upgradeable_ins_acc_idx::Write::Authority as usize),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Buffer authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -519,7 +523,7 @@ fn process_loader_upgradeable_instruction(
|
|||
)?;
|
||||
write_program_data(
|
||||
&mut program,
|
||||
UpgradeableLoaderState::buffer_data_offset()? + offset as usize,
|
||||
UpgradeableLoaderState::buffer_data_offset()?.saturating_add(offset as usize),
|
||||
&bytes,
|
||||
invoke_context.get_log_collector(),
|
||||
)?;
|
||||
|
@ -582,8 +586,12 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::DeployWithMaxDataLen::UpgradeAuthority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(
|
||||
upgradeable_ins_acc_idx::DeployWithMaxDataLen::UpgradeAuthority
|
||||
as usize,
|
||||
),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Upgrade authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -662,7 +670,7 @@ fn process_loader_upgradeable_instruction(
|
|||
|
||||
// Load and verify the program bits
|
||||
let executor = create_executor(
|
||||
first_instruction_account + 3,
|
||||
first_instruction_account.saturating_add(3),
|
||||
buffer_data_offset,
|
||||
invoke_context,
|
||||
use_jit,
|
||||
|
@ -687,8 +695,8 @@ fn process_loader_upgradeable_instruction(
|
|||
slot: clock.slot,
|
||||
upgrade_authority_address,
|
||||
})?;
|
||||
programdata.get_data_mut()
|
||||
[programdata_data_offset..programdata_data_offset + buffer_data_len]
|
||||
programdata.get_data_mut()[programdata_data_offset
|
||||
..programdata_data_offset.saturating_add(buffer_data_len)]
|
||||
.copy_from_slice(&buffer.get_data()[buffer_data_offset..]);
|
||||
}
|
||||
|
||||
|
@ -783,8 +791,11 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::Upgrade::UpgradeAuthority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(
|
||||
upgradeable_ins_acc_idx::Upgrade::UpgradeAuthority as usize,
|
||||
),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Upgrade authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -817,7 +828,11 @@ fn process_loader_upgradeable_instruction(
|
|||
ic_logger_msg!(log_collector, "ProgramData account not large enough");
|
||||
return Err(InstructionError::AccountDataTooSmall);
|
||||
}
|
||||
if programdata.get_lamports() + buffer.get_lamports() < programdata_balance_required {
|
||||
if programdata
|
||||
.get_lamports()
|
||||
.saturating_add(buffer.get_lamports())
|
||||
< programdata_balance_required
|
||||
{
|
||||
ic_logger_msg!(
|
||||
log_collector,
|
||||
"Buffer account balance too low to fund upgrade"
|
||||
|
@ -839,8 +854,11 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::Upgrade::UpgradeAuthority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(
|
||||
upgradeable_ins_acc_idx::Upgrade::UpgradeAuthority as usize,
|
||||
),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Upgrade authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -853,7 +871,7 @@ fn process_loader_upgradeable_instruction(
|
|||
|
||||
// Load and verify the program bits
|
||||
let executor = create_executor(
|
||||
first_instruction_account + 2,
|
||||
first_instruction_account.saturating_add(2),
|
||||
buffer_data_offset,
|
||||
invoke_context,
|
||||
use_jit,
|
||||
|
@ -878,9 +896,10 @@ fn process_loader_upgradeable_instruction(
|
|||
upgrade_authority_address: current_upgrade_authority_address,
|
||||
})?;
|
||||
programdata.get_data_mut()
|
||||
[programdata_data_offset..programdata_data_offset + buffer_data_len]
|
||||
[programdata_data_offset..programdata_data_offset.saturating_add(buffer_data_len)]
|
||||
.copy_from_slice(&buffer.get_data()[buffer_data_offset..]);
|
||||
programdata.get_data_mut()[programdata_data_offset + buffer_data_len..].fill(0);
|
||||
programdata.get_data_mut()[programdata_data_offset.saturating_add(buffer_data_len)..]
|
||||
.fill(0);
|
||||
|
||||
// Fund ProgramData to rent-exemption, spill the rest
|
||||
{
|
||||
|
@ -889,7 +908,9 @@ fn process_loader_upgradeable_instruction(
|
|||
upgradeable_ins_acc_idx::Upgrade::Spill as usize,
|
||||
)?;
|
||||
spill.checked_add_lamports(
|
||||
(programdata.get_lamports() + buffer.get_lamports())
|
||||
(programdata
|
||||
.get_lamports()
|
||||
.saturating_add(buffer.get_lamports()))
|
||||
.saturating_sub(programdata_balance_required),
|
||||
)?;
|
||||
buffer.set_lamports(0);
|
||||
|
@ -931,8 +952,11 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::SetAuthority::CurrentAuthority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(
|
||||
upgradeable_ins_acc_idx::SetAuthority::CurrentAuthority as usize,
|
||||
),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Buffer authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -954,8 +978,11 @@ fn process_loader_upgradeable_instruction(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::SetAuthority::CurrentAuthority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(
|
||||
upgradeable_ins_acc_idx::SetAuthority::CurrentAuthority as usize,
|
||||
),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Upgrade authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -976,9 +1003,11 @@ fn process_loader_upgradeable_instruction(
|
|||
UpgradeableLoaderInstruction::Close => {
|
||||
instruction_context.check_number_of_instruction_accounts(2)?;
|
||||
if instruction_context.get_index_in_transaction(
|
||||
first_instruction_account + upgradeable_ins_acc_idx::Close::Account as usize,
|
||||
first_instruction_account
|
||||
.saturating_add(upgradeable_ins_acc_idx::Close::Account as usize),
|
||||
)? == instruction_context.get_index_in_transaction(
|
||||
first_instruction_account + upgradeable_ins_acc_idx::Close::Recipient as usize,
|
||||
first_instruction_account
|
||||
.saturating_add(upgradeable_ins_acc_idx::Close::Recipient as usize),
|
||||
)? {
|
||||
ic_logger_msg!(
|
||||
log_collector,
|
||||
|
@ -1029,8 +1058,9 @@ fn process_loader_upgradeable_instruction(
|
|||
} => {
|
||||
instruction_context.check_number_of_instruction_accounts(4)?;
|
||||
if !instruction_context.is_writable(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::Close::Program as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(upgradeable_ins_acc_idx::Close::Program as usize),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Program account is not writable");
|
||||
return Err(InstructionError::InvalidArgument);
|
||||
|
@ -1105,8 +1135,9 @@ fn common_close_account(
|
|||
return Err(InstructionError::IncorrectAuthority);
|
||||
}
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ upgradeable_ins_acc_idx::Close::Authority as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(upgradeable_ins_acc_idx::Close::Authority as usize),
|
||||
)? {
|
||||
ic_logger_msg!(log_collector, "Authority did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -1158,8 +1189,9 @@ fn process_loader_instruction(
|
|||
match limited_deserialize(instruction_data)? {
|
||||
LoaderInstruction::Write { offset, bytes } => {
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ deprecated_ins_acc_idx::Write::Program as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(deprecated_ins_acc_idx::Write::Program as usize),
|
||||
)? {
|
||||
ic_msg!(invoke_context, "Program account did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -1176,8 +1208,9 @@ fn process_loader_instruction(
|
|||
}
|
||||
LoaderInstruction::Finalize => {
|
||||
if !instruction_context.is_signer(
|
||||
instruction_context.get_number_of_program_accounts()
|
||||
+ deprecated_ins_acc_idx::Finalize::Program as usize,
|
||||
instruction_context
|
||||
.get_number_of_program_accounts()
|
||||
.saturating_add(deprecated_ins_acc_idx::Finalize::Program as usize),
|
||||
)? {
|
||||
ic_msg!(invoke_context, "Program account did not sign");
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
|
@ -1281,7 +1314,7 @@ impl Executor for BpfExecutor {
|
|||
log_collector,
|
||||
"Program {} consumed {} of {} compute units",
|
||||
&program_id,
|
||||
before - after,
|
||||
before.saturating_sub(after),
|
||||
before
|
||||
);
|
||||
if log_enabled!(Trace) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
use {
|
||||
byteorder::{ByteOrder, LittleEndian, WriteBytesExt},
|
||||
solana_rbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN},
|
||||
|
|
|
@ -1037,7 +1037,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a, 'b> {
|
|||
return;
|
||||
}
|
||||
}
|
||||
bump_seed[0] -= 1;
|
||||
bump_seed[0] = bump_seed[0].saturating_sub(1);
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
}
|
||||
*result = Ok(1);
|
||||
|
@ -1115,10 +1115,12 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
|
|||
compute_budget.mem_op_base_cost.max(
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul(val.len() as u64 / 2),
|
||||
.saturating_mul((val.len() as u64).saturating_div(2)),
|
||||
)
|
||||
} else {
|
||||
compute_budget.sha256_byte_cost * (val.len() as u64 / 2)
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul((val.len() as u64).saturating_div(2))
|
||||
};
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
hasher.hash(bytes);
|
||||
|
@ -1136,9 +1138,12 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
|
|||
memory_mapping: &MemoryMapping,
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<u64, EbpfError<BpfError>> {
|
||||
invoke_context.get_compute_meter().consume(
|
||||
invoke_context
|
||||
.get_compute_meter()
|
||||
.consume(invoke_context.get_compute_budget().sysvar_base_cost + size_of::<T>() as u64)?;
|
||||
.get_compute_budget()
|
||||
.sysvar_base_cost
|
||||
.saturating_add(size_of::<T>() as u64),
|
||||
)?;
|
||||
let var = translate_type_mut::<T>(memory_mapping, var_addr, loader_id)?;
|
||||
|
||||
let sysvar: Arc<T> = sysvar.map_err(SyscallError::InstructionError)?;
|
||||
|
@ -1349,10 +1354,12 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
|
|||
compute_budget.mem_op_base_cost.max(
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul(val.len() as u64 / 2),
|
||||
.saturating_mul((val.len() as u64).saturating_div(2)),
|
||||
)
|
||||
} else {
|
||||
compute_budget.sha256_byte_cost * (val.len() as u64 / 2)
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul((val.len() as u64).saturating_div(2))
|
||||
};
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
hasher.hash(bytes);
|
||||
|
@ -1366,8 +1373,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
|
|||
/// This function is incorrect due to arithmetic overflow and only exists for
|
||||
/// backwards compatibility. Instead use program_stubs::is_nonoverlapping.
|
||||
fn check_overlapping_do_not_use(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)
|
||||
(src_addr <= dst_addr && src_addr.saturating_add(n) > dst_addr)
|
||||
|| (dst_addr <= src_addr && dst_addr.saturating_add(n) > src_addr)
|
||||
}
|
||||
|
||||
fn mem_op_consume<'a, 'b>(
|
||||
|
@ -1381,9 +1388,9 @@ fn mem_op_consume<'a, 'b>(
|
|||
{
|
||||
compute_budget
|
||||
.mem_op_base_cost
|
||||
.max(n / compute_budget.cpi_bytes_per_unit)
|
||||
.max(n.saturating_div(compute_budget.cpi_bytes_per_unit))
|
||||
} else {
|
||||
n / compute_budget.cpi_bytes_per_unit
|
||||
n.saturating_div(compute_budget.cpi_bytes_per_unit)
|
||||
};
|
||||
invoke_context.get_compute_meter().consume(cost)
|
||||
}
|
||||
|
@ -1417,7 +1424,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
|
|||
if update_syscall_base_costs {
|
||||
let cost = compute_budget
|
||||
.mem_op_base_cost
|
||||
.max(n / compute_budget.cpi_bytes_per_unit);
|
||||
.max(n.saturating_div(compute_budget.cpi_bytes_per_unit));
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1446,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
|
|||
}
|
||||
|
||||
if !update_syscall_base_costs {
|
||||
let cost = n / compute_budget.cpi_bytes_per_unit;
|
||||
let cost = n.saturating_div(compute_budget.cpi_bytes_per_unit);
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
};
|
||||
|
||||
|
@ -1537,11 +1544,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcmp<'a, 'b> {
|
|||
let a = s1[i];
|
||||
let b = s2[i];
|
||||
if a != b {
|
||||
*cmp_result = a as i32 - b as i32;
|
||||
*cmp_result = (a as i32).saturating_sub(b as i32);
|
||||
*result = Ok(0);
|
||||
return;
|
||||
}
|
||||
i += 1;
|
||||
i = i.saturating_add(1);
|
||||
}
|
||||
*cmp_result = 0;
|
||||
*result = Ok(0);
|
||||
|
@ -1924,10 +1931,12 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
|
|||
compute_budget.mem_op_base_cost.max(
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul(val.len() as u64 / 2),
|
||||
.saturating_mul((val.len() as u64).saturating_div(2)),
|
||||
)
|
||||
} else {
|
||||
compute_budget.sha256_byte_cost * (val.len() as u64 / 2)
|
||||
compute_budget
|
||||
.sha256_byte_cost
|
||||
.saturating_mul((val.len() as u64).saturating_div(2))
|
||||
};
|
||||
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||
hasher.hash(bytes);
|
||||
|
@ -2082,7 +2091,8 @@ impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedRust<'a, 'b> {
|
|||
)?;
|
||||
|
||||
invoke_context.get_compute_meter().consume(
|
||||
data.len() as u64 / invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
(data.len() as u64)
|
||||
.saturating_div(invoke_context.get_compute_budget().cpi_bytes_per_unit),
|
||||
)?;
|
||||
|
||||
let translated = translate(
|
||||
|
@ -2352,7 +2362,9 @@ impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedC<'a, 'b> {
|
|||
let vm_data_addr = account_info.data_addr;
|
||||
|
||||
invoke_context.get_compute_meter().consume(
|
||||
account_info.data_len / invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
account_info
|
||||
.data_len
|
||||
.saturating_div(invoke_context.get_compute_budget().cpi_bytes_per_unit),
|
||||
)?;
|
||||
|
||||
let data = translate_slice_mut::<u8>(
|
||||
|
@ -2364,7 +2376,7 @@ impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedC<'a, 'b> {
|
|||
|
||||
let first_info_addr = &account_infos[0] as *const _ as u64;
|
||||
let addr = &account_info.data_len as *const u64 as u64;
|
||||
let vm_addr = account_infos_addr + (addr - first_info_addr);
|
||||
let vm_addr = account_infos_addr.saturating_add(addr.saturating_sub(first_info_addr));
|
||||
let _ = translate(
|
||||
memory_mapping,
|
||||
AccessType::Store,
|
||||
|
@ -2580,7 +2592,9 @@ fn check_account_infos(
|
|||
len: usize,
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), EbpfError<BpfError>> {
|
||||
if len * size_of::<Pubkey>() > invoke_context.get_compute_budget().max_cpi_instruction_size {
|
||||
if len.saturating_mul(size_of::<Pubkey>())
|
||||
> invoke_context.get_compute_budget().max_cpi_instruction_size
|
||||
{
|
||||
// Cap the number of account_infos a caller can pass to approximate
|
||||
// maximum that accounts that could be passed in an instruction
|
||||
return Err(SyscallError::TooManyAccounts.into());
|
||||
|
@ -2710,9 +2724,16 @@ fn call<'a, 'b: 'a>(
|
|||
);
|
||||
}
|
||||
let data_overflow = if do_support_realloc {
|
||||
new_len > caller_account.original_data_len + MAX_PERMITTED_DATA_INCREASE
|
||||
new_len
|
||||
> caller_account
|
||||
.original_data_len
|
||||
.saturating_add(MAX_PERMITTED_DATA_INCREASE)
|
||||
} else {
|
||||
new_len > caller_account.data.len() + MAX_PERMITTED_DATA_INCREASE
|
||||
new_len
|
||||
> caller_account
|
||||
.data
|
||||
.len()
|
||||
.saturating_add(MAX_PERMITTED_DATA_INCREASE)
|
||||
};
|
||||
if data_overflow {
|
||||
ic_msg!(
|
||||
|
@ -2770,9 +2791,10 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
|
|||
let budget = invoke_context.get_compute_budget();
|
||||
|
||||
question_mark!(
|
||||
invoke_context
|
||||
.get_compute_meter()
|
||||
.consume(len / budget.cpi_bytes_per_unit + budget.syscall_base_cost),
|
||||
invoke_context.get_compute_meter().consume(
|
||||
len.saturating_div(budget.cpi_bytes_per_unit)
|
||||
.saturating_add(budget.syscall_base_cost)
|
||||
),
|
||||
result
|
||||
);
|
||||
|
||||
|
@ -2845,9 +2867,10 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
|
|||
length = length.min(return_data.len() as u64);
|
||||
if length != 0 {
|
||||
question_mark!(
|
||||
invoke_context
|
||||
.get_compute_meter()
|
||||
.consume((length + size_of::<Pubkey>() as u64) / budget.cpi_bytes_per_unit),
|
||||
invoke_context.get_compute_meter().consume(
|
||||
(length.saturating_add(size_of::<Pubkey>() as u64))
|
||||
.saturating_div(budget.cpi_bytes_per_unit)
|
||||
),
|
||||
result
|
||||
);
|
||||
|
||||
|
@ -2994,7 +3017,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
|
|||
if index == current_index {
|
||||
return true;
|
||||
} else {
|
||||
current_index += 1;
|
||||
current_index = current_index.saturating_add(1);
|
||||
}
|
||||
}
|
||||
false
|
||||
|
@ -4190,7 +4213,7 @@ mod tests {
|
|||
MemoryRegion {
|
||||
host_addr: mock_slices.as_ptr() as u64,
|
||||
vm_addr: SEEDS_VA,
|
||||
len: (seeds.len() * size_of::<MockSlice>()) as u64,
|
||||
len: (seeds.len().saturating_mul(size_of::<MockSlice>()) as u64),
|
||||
vm_gap_shift: 63,
|
||||
is_writable: false,
|
||||
},
|
||||
|
@ -4218,7 +4241,7 @@ mod tests {
|
|||
];
|
||||
|
||||
for (i, seed) in seeds.iter().enumerate() {
|
||||
let vm_addr = SEED_VA + (i as u64 * 0x100000000);
|
||||
let vm_addr = SEED_VA.saturating_add((i as u64).saturating_mul(0x100000000));
|
||||
let mock_slice = MockSlice {
|
||||
vm_addr,
|
||||
len: seed.len(),
|
||||
|
|
Loading…
Reference in New Issue