featurize loader sat math (#23516)

This commit is contained in:
Jack May 2022-03-08 11:48:22 -08:00 committed by GitHub
parent 536a99705b
commit c2ec294401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 30 deletions

View File

@ -26,7 +26,7 @@ use {
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, update_syscall_base_costs,
sol_log_data_syscall_enabled, syscall_saturated_math, update_syscall_base_costs,
},
hash::{Hasher, HASH_BYTES},
instruction::{
@ -1544,10 +1544,20 @@ 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).saturating_sub(b as i32);
*cmp_result = if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
(a as i32).saturating_sub(b as i32)
} else {
#[allow(clippy::integer_arithmetic)]
{
a as i32 - b as i32
}
};
*result = Ok(0);
return;
}
};
i = i.saturating_add(1);
}
*cmp_result = 0;
@ -1933,10 +1943,18 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
.sha256_byte_cost
.saturating_mul((val.len() as u64).saturating_div(2)),
)
} else {
} else if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
compute_budget
.sha256_byte_cost
.saturating_mul((val.len() as u64).saturating_div(2))
} else {
#[allow(clippy::integer_arithmetic)]
{
compute_budget.sha256_byte_cost * (val.len() as u64 / 2)
}
};
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
hasher.hash(bytes);
@ -2376,7 +2394,17 @@ 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.saturating_add(addr.saturating_sub(first_info_addr));
let vm_addr = if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
account_infos_addr.saturating_add(addr.saturating_sub(first_info_addr))
} else {
#[allow(clippy::integer_arithmetic)]
{
account_infos_addr + (addr - first_info_addr)
}
};
let _ = translate(
memory_mapping,
AccessType::Store,
@ -2592,9 +2620,18 @@ fn check_account_infos(
len: usize,
invoke_context: &mut InvokeContext,
) -> Result<(), EbpfError<BpfError>> {
if len.saturating_mul(size_of::<Pubkey>())
> invoke_context.get_compute_budget().max_cpi_instruction_size
let adjusted_len = if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
len.saturating_mul(size_of::<Pubkey>())
} else {
#[allow(clippy::integer_arithmetic)]
{
len * size_of::<Pubkey>()
}
};
if adjusted_len > 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());
@ -2724,16 +2761,34 @@ fn call<'a, 'b: 'a>(
);
}
let data_overflow = if do_support_realloc {
new_len
> caller_account
.original_data_len
.saturating_add(MAX_PERMITTED_DATA_INCREASE)
} else {
if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
new_len
> caller_account
.original_data_len
.saturating_add(MAX_PERMITTED_DATA_INCREASE)
} else {
#[allow(clippy::integer_arithmetic)]
{
new_len > caller_account.original_data_len + MAX_PERMITTED_DATA_INCREASE
}
}
} else if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
new_len
> caller_account
.data
.len()
.saturating_add(MAX_PERMITTED_DATA_INCREASE)
} else {
#[allow(clippy::integer_arithmetic)]
{
new_len > caller_account.data.len() + MAX_PERMITTED_DATA_INCREASE
}
};
if data_overflow {
ic_msg!(
@ -2790,13 +2845,19 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
let budget = invoke_context.get_compute_budget();
question_mark!(
invoke_context.get_compute_meter().consume(
len.saturating_div(budget.cpi_bytes_per_unit)
.saturating_add(budget.syscall_base_cost)
),
result
);
let cost = if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
len.saturating_div(budget.cpi_bytes_per_unit)
.saturating_add(budget.syscall_base_cost)
} else {
#[allow(clippy::integer_arithmetic)]
{
len / budget.cpi_bytes_per_unit + budget.syscall_base_cost
}
};
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
if len > MAX_RETURN_DATA as u64 {
*result = Err(SyscallError::ReturnDataTooLarge(len, MAX_RETURN_DATA as u64).into());
@ -2866,13 +2927,20 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
let (program_id, return_data) = invoke_context.transaction_context.get_return_data();
length = length.min(return_data.len() as u64);
if length != 0 {
question_mark!(
invoke_context.get_compute_meter().consume(
(length.saturating_add(size_of::<Pubkey>() as u64))
.saturating_div(budget.cpi_bytes_per_unit)
),
result
);
let cost = if invoke_context
.feature_set
.is_active(&syscall_saturated_math::id())
{
length
.saturating_add(size_of::<Pubkey>() as u64)
.saturating_div(budget.cpi_bytes_per_unit)
} else {
#[allow(clippy::integer_arithmetic)]
{
(length + size_of::<Pubkey>() as u64) / budget.cpi_bytes_per_unit
}
};
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let return_data_result = question_mark!(
translate_slice_mut::<u8>(memory_mapping, return_data_addr, length, loader_id),

View File

@ -315,6 +315,10 @@ pub mod record_instruction_in_transaction_context_push {
solana_sdk::declare_id!("3aJdcZqxoLpSBxgeYGjPwaYS1zzcByxUDqJkbzWAH1Zb");
}
pub mod syscall_saturated_math {
solana_sdk::declare_id!("HyrbKftCdJ5CrUfEti6x26Cj7rZLNe32weugk7tLcWb8");
}
lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@ -384,10 +388,11 @@ lazy_static! {
(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"),
(add_get_processed_sibling_instruction_syscall::id(), "add add_get_processed_sibling_instruction_syscall"),
(bank_tranaction_count_fix::id(), "Fixes Bank::transaction_count to include all committed transactions, not just successful ones"),
(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"),
(bank_tranaction_count_fix::id(), "fixes Bank::transaction_count to include all committed transactions, not just successful ones"),
(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"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()