|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
|
use crate::{alloc, BPFError};
|
|
|
|
|
use crate::{alloc, BpfError};
|
|
|
|
|
use alloc::Alloc;
|
|
|
|
|
use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar};
|
|
|
|
|
use solana_rbpf::{
|
|
|
|
@@ -73,17 +73,17 @@ pub enum SyscallError {
|
|
|
|
|
#[error("Too many accounts passed to inner instruction")]
|
|
|
|
|
TooManyAccounts,
|
|
|
|
|
}
|
|
|
|
|
impl From<SyscallError> for EbpfError<BPFError> {
|
|
|
|
|
impl From<SyscallError> for EbpfError<BpfError> {
|
|
|
|
|
fn from(error: SyscallError) -> Self {
|
|
|
|
|
EbpfError::UserError(error.into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait SyscallConsume {
|
|
|
|
|
fn consume(&mut self, amount: u64) -> Result<(), EbpfError<BPFError>>;
|
|
|
|
|
fn consume(&mut self, amount: u64) -> Result<(), EbpfError<BpfError>>;
|
|
|
|
|
}
|
|
|
|
|
impl SyscallConsume for Rc<RefCell<dyn ComputeMeter>> {
|
|
|
|
|
fn consume(&mut self, amount: u64) -> Result<(), EbpfError<BPFError>> {
|
|
|
|
|
fn consume(&mut self, amount: u64) -> Result<(), EbpfError<BpfError>> {
|
|
|
|
|
self.try_borrow_mut()
|
|
|
|
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed)?
|
|
|
|
|
.consume(amount)
|
|
|
|
@@ -98,11 +98,11 @@ impl SyscallConsume for Rc<RefCell<dyn ComputeMeter>> {
|
|
|
|
|
/// Only one allocator is currently supported
|
|
|
|
|
|
|
|
|
|
/// Simple bump allocator, never frees
|
|
|
|
|
use crate::allocator_bump::BPFAllocator;
|
|
|
|
|
use crate::allocator_bump::BpfAllocator;
|
|
|
|
|
|
|
|
|
|
pub fn register_syscalls(
|
|
|
|
|
invoke_context: &mut dyn InvokeContext,
|
|
|
|
|
) -> Result<SyscallRegistry, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<SyscallRegistry, EbpfError<BpfError>> {
|
|
|
|
|
let mut syscall_registry = SyscallRegistry::default();
|
|
|
|
|
|
|
|
|
|
syscall_registry.register_syscall_by_name(b"abort", SyscallAbort::call)?;
|
|
|
|
@@ -162,11 +162,11 @@ macro_rules! bind_feature_gated_syscall_context_object {
|
|
|
|
|
|
|
|
|
|
pub fn bind_syscall_context_objects<'a>(
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
vm: &mut EbpfVm<'a, BPFError, crate::ThisInstructionMeter>,
|
|
|
|
|
vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>,
|
|
|
|
|
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
|
|
|
|
invoke_context: &'a mut dyn InvokeContext,
|
|
|
|
|
heap: Vec<u8>,
|
|
|
|
|
) -> Result<(), EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<(), EbpfError<BpfError>> {
|
|
|
|
|
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
|
|
|
|
|
|
|
|
|
// Syscall functions common across languages
|
|
|
|
@@ -293,7 +293,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|
|
|
|
vm.bind_syscall_context_object(
|
|
|
|
|
Box::new(SyscallAllocFree {
|
|
|
|
|
aligned: *loader_id != bpf_loader_deprecated::id(),
|
|
|
|
|
allocator: BPFAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
allocator: BpfAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
}),
|
|
|
|
|
None,
|
|
|
|
|
)?;
|
|
|
|
@@ -306,8 +306,8 @@ fn translate(
|
|
|
|
|
access_type: AccessType,
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
len: u64,
|
|
|
|
|
) -> Result<u64, EbpfError<BPFError>> {
|
|
|
|
|
memory_mapping.map::<BPFError>(access_type, vm_addr, len)
|
|
|
|
|
) -> Result<u64, EbpfError<BpfError>> {
|
|
|
|
|
memory_mapping.map::<BpfError>(access_type, vm_addr, len)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn translate_type_inner<'a, T>(
|
|
|
|
@@ -315,7 +315,7 @@ fn translate_type_inner<'a, T>(
|
|
|
|
|
access_type: AccessType,
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a mut T, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a mut T, EbpfError<BpfError>> {
|
|
|
|
|
if loader_id != &bpf_loader_deprecated::id()
|
|
|
|
|
&& (vm_addr as u64 as *mut T).align_offset(align_of::<T>()) != 0
|
|
|
|
|
{
|
|
|
|
@@ -333,14 +333,14 @@ fn translate_type_mut<'a, T>(
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a mut T, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a mut T, EbpfError<BpfError>> {
|
|
|
|
|
translate_type_inner::<T>(memory_mapping, AccessType::Store, vm_addr, loader_id)
|
|
|
|
|
}
|
|
|
|
|
fn translate_type<'a, T>(
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a T, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a T, EbpfError<BpfError>> {
|
|
|
|
|
match translate_type_inner::<T>(memory_mapping, AccessType::Load, vm_addr, loader_id) {
|
|
|
|
|
Ok(value) => Ok(&*value),
|
|
|
|
|
Err(e) => Err(e),
|
|
|
|
@@ -353,7 +353,7 @@ fn translate_slice_inner<'a, T>(
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
len: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a mut [T], EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a mut [T], EbpfError<BpfError>> {
|
|
|
|
|
if loader_id != &bpf_loader_deprecated::id()
|
|
|
|
|
&& (vm_addr as u64 as *mut T).align_offset(align_of::<T>()) != 0
|
|
|
|
|
{
|
|
|
|
@@ -377,7 +377,7 @@ fn translate_slice_mut<'a, T>(
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
len: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a mut [T], EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a mut [T], EbpfError<BpfError>> {
|
|
|
|
|
translate_slice_inner::<T>(memory_mapping, AccessType::Store, vm_addr, len, loader_id)
|
|
|
|
|
}
|
|
|
|
|
fn translate_slice<'a, T>(
|
|
|
|
@@ -385,7 +385,7 @@ fn translate_slice<'a, T>(
|
|
|
|
|
vm_addr: u64,
|
|
|
|
|
len: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<&'a [T], EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<&'a [T], EbpfError<BpfError>> {
|
|
|
|
|
match translate_slice_inner::<T>(memory_mapping, AccessType::Load, vm_addr, len, loader_id) {
|
|
|
|
|
Ok(value) => Ok(&*value),
|
|
|
|
|
Err(e) => Err(e),
|
|
|
|
@@ -399,8 +399,8 @@ fn translate_string_and_do(
|
|
|
|
|
addr: u64,
|
|
|
|
|
len: u64,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
work: &mut dyn FnMut(&str) -> Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
) -> Result<u64, EbpfError<BPFError>> {
|
|
|
|
|
work: &mut dyn FnMut(&str) -> Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) -> Result<u64, EbpfError<BpfError>> {
|
|
|
|
|
let buf = translate_slice::<u8>(memory_mapping, addr, len, loader_id)?;
|
|
|
|
|
let i = match buf.iter().position(|byte| *byte == 0) {
|
|
|
|
|
Some(i) => i,
|
|
|
|
@@ -417,7 +417,7 @@ fn translate_string_and_do(
|
|
|
|
|
/// `abort()` is not intended to be called explicitly by the program.
|
|
|
|
|
/// Causes the BPF program to be halted immediately
|
|
|
|
|
pub struct SyscallAbort {}
|
|
|
|
|
impl SyscallObject<BPFError> for SyscallAbort {
|
|
|
|
|
impl SyscallObject<BpfError> for SyscallAbort {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
_arg1: u64,
|
|
|
|
@@ -426,7 +426,7 @@ impl SyscallObject<BPFError> for SyscallAbort {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
_memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
*result = Err(SyscallError::Abort.into());
|
|
|
|
|
}
|
|
|
|
@@ -439,7 +439,7 @@ pub struct SyscallPanic<'a> {
|
|
|
|
|
compute_meter: Option<Rc<RefCell<dyn ComputeMeter>>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallPanic<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallPanic<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
file: u64,
|
|
|
|
@@ -448,7 +448,7 @@ impl<'a> SyscallObject<BPFError> for SyscallPanic<'a> {
|
|
|
|
|
column: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
if let Some(ref mut compute_meter) = self.compute_meter {
|
|
|
|
|
question_mark!(compute_meter.consume(len), result);
|
|
|
|
@@ -471,7 +471,7 @@ pub struct SyscallLog<'a> {
|
|
|
|
|
logger: Rc<RefCell<dyn Logger>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallLog<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallLog<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
addr: u64,
|
|
|
|
@@ -480,7 +480,7 @@ impl<'a> SyscallObject<BPFError> for SyscallLog<'a> {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
if self.per_byte_cost {
|
|
|
|
|
question_mark!(self.compute_meter.consume(len), result);
|
|
|
|
@@ -510,7 +510,7 @@ pub struct SyscallLogU64 {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
logger: Rc<RefCell<dyn Logger>>,
|
|
|
|
|
}
|
|
|
|
|
impl SyscallObject<BPFError> for SyscallLogU64 {
|
|
|
|
|
impl SyscallObject<BpfError> for SyscallLogU64 {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
arg1: u64,
|
|
|
|
@@ -519,7 +519,7 @@ impl SyscallObject<BPFError> for SyscallLogU64 {
|
|
|
|
|
arg4: u64,
|
|
|
|
|
arg5: u64,
|
|
|
|
|
_memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
|
|
|
|
stable_log::program_log(
|
|
|
|
@@ -539,7 +539,7 @@ pub struct SyscallLogBpfComputeUnits {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
logger: Rc<RefCell<dyn Logger>>,
|
|
|
|
|
}
|
|
|
|
|
impl SyscallObject<BPFError> for SyscallLogBpfComputeUnits {
|
|
|
|
|
impl SyscallObject<BpfError> for SyscallLogBpfComputeUnits {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
_arg1: u64,
|
|
|
|
@@ -548,7 +548,7 @@ impl SyscallObject<BPFError> for SyscallLogBpfComputeUnits {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
_memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
|
|
|
|
let logger = question_mark!(
|
|
|
|
@@ -574,7 +574,7 @@ pub struct SyscallLogPubkey<'a> {
|
|
|
|
|
logger: Rc<RefCell<dyn Logger>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallLogPubkey<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallLogPubkey<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
pubkey_addr: u64,
|
|
|
|
@@ -583,7 +583,7 @@ impl<'a> SyscallObject<BPFError> for SyscallLogPubkey<'a> {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
|
|
|
|
let pubkey = question_mark!(
|
|
|
|
@@ -603,9 +603,9 @@ impl<'a> SyscallObject<BPFError> for SyscallLogPubkey<'a> {
|
|
|
|
|
/// to the VM to use for enforcement.
|
|
|
|
|
pub struct SyscallAllocFree {
|
|
|
|
|
aligned: bool,
|
|
|
|
|
allocator: BPFAllocator,
|
|
|
|
|
allocator: BpfAllocator,
|
|
|
|
|
}
|
|
|
|
|
impl SyscallObject<BPFError> for SyscallAllocFree {
|
|
|
|
|
impl SyscallObject<BpfError> for SyscallAllocFree {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
size: u64,
|
|
|
|
@@ -614,7 +614,7 @@ impl SyscallObject<BPFError> for SyscallAllocFree {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
_memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
let align = if self.aligned {
|
|
|
|
|
align_of::<u128>()
|
|
|
|
@@ -646,7 +646,7 @@ fn translate_program_address_inputs<'a>(
|
|
|
|
|
program_id_addr: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
loader_id: &Pubkey,
|
|
|
|
|
) -> Result<(Vec<&'a [u8]>, &'a Pubkey), EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<(Vec<&'a [u8]>, &'a Pubkey), EbpfError<BpfError>> {
|
|
|
|
|
let untranslated_seeds =
|
|
|
|
|
translate_slice::<&[&u8]>(memory_mapping, seeds_addr, seeds_len, loader_id)?;
|
|
|
|
|
if untranslated_seeds.len() > MAX_SEEDS {
|
|
|
|
@@ -662,7 +662,7 @@ fn translate_program_address_inputs<'a>(
|
|
|
|
|
loader_id,
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
|
|
|
|
let program_id = translate_type::<Pubkey>(memory_mapping, program_id_addr, loader_id)?;
|
|
|
|
|
Ok((seeds, program_id))
|
|
|
|
|
}
|
|
|
|
@@ -673,7 +673,7 @@ struct SyscallCreateProgramAddress<'a> {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
seeds_addr: u64,
|
|
|
|
@@ -682,7 +682,7 @@ impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
|
|
|
|
|
address_addr: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
let (seeds, program_id) = question_mark!(
|
|
|
|
|
translate_program_address_inputs(
|
|
|
|
@@ -718,7 +718,7 @@ struct SyscallTryFindProgramAddress<'a> {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallTryFindProgramAddress<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
seeds_addr: u64,
|
|
|
|
@@ -727,7 +727,7 @@ impl<'a> SyscallObject<BPFError> for SyscallTryFindProgramAddress<'a> {
|
|
|
|
|
address_addr: u64,
|
|
|
|
|
bump_seed_addr: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
let (seeds, program_id) = question_mark!(
|
|
|
|
|
translate_program_address_inputs(
|
|
|
|
@@ -777,7 +777,7 @@ pub struct SyscallSha256<'a> {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallSha256<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallSha256<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
vals_addr: u64,
|
|
|
|
@@ -786,7 +786,7 @@ impl<'a> SyscallObject<BPFError> for SyscallSha256<'a> {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
question_mark!(self.compute_meter.consume(self.sha256_base_cost), result);
|
|
|
|
|
let hash_result = question_mark!(
|
|
|
|
@@ -833,7 +833,7 @@ pub struct SyscallRistrettoMul<'a> {
|
|
|
|
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallRistrettoMul<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallRistrettoMul<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
point_addr: u64,
|
|
|
|
@@ -842,7 +842,7 @@ impl<'a> SyscallObject<BPFError> for SyscallRistrettoMul<'a> {
|
|
|
|
|
_arg4: u64,
|
|
|
|
|
_arg5: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
|
|
|
|
|
|
|
|
@@ -882,14 +882,14 @@ type TranslatedAccounts<'a> = (
|
|
|
|
|
|
|
|
|
|
/// Implemented by language specific data structure translators
|
|
|
|
|
trait SyscallInvokeSigned<'a> {
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>>;
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BPFError>>;
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
|
|
|
|
fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>];
|
|
|
|
|
fn translate_instruction(
|
|
|
|
|
&self,
|
|
|
|
|
addr: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Instruction, EbpfError<BPFError>>;
|
|
|
|
|
) -> Result<Instruction, EbpfError<BpfError>>;
|
|
|
|
|
fn translate_accounts(
|
|
|
|
|
&self,
|
|
|
|
|
account_keys: &[Pubkey],
|
|
|
|
@@ -897,14 +897,14 @@ trait SyscallInvokeSigned<'a> {
|
|
|
|
|
account_infos_addr: u64,
|
|
|
|
|
account_infos_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BPFError>>;
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>;
|
|
|
|
|
fn translate_signers(
|
|
|
|
|
&self,
|
|
|
|
|
program_id: &Pubkey,
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BPFError>>;
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BpfError>>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Cross-program invocation called from Rust
|
|
|
|
@@ -914,12 +914,12 @@ pub struct SyscallInvokeSignedRust<'a> {
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
|
|
|
|
self.invoke_context
|
|
|
|
|
.try_borrow_mut()
|
|
|
|
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
|
|
|
|
}
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
|
|
|
|
self.invoke_context
|
|
|
|
|
.try_borrow()
|
|
|
|
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
|
|
|
@@ -931,7 +931,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
&self,
|
|
|
|
|
addr: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Instruction, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<Instruction, EbpfError<BpfError>> {
|
|
|
|
|
let ix = translate_type::<Instruction>(memory_mapping, addr, self.loader_id)?;
|
|
|
|
|
|
|
|
|
|
check_instruction_size(
|
|
|
|
@@ -968,7 +968,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
account_infos_addr: u64,
|
|
|
|
|
account_infos_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
|
|
|
|
|
let invoke_context = self.invoke_context.borrow();
|
|
|
|
|
|
|
|
|
|
let account_infos = translate_slice::<AccountInfo>(
|
|
|
|
@@ -987,7 +987,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
self.loader_id,
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
|
|
|
|
|
|
|
|
|
let translate = |account_info: &AccountInfo| {
|
|
|
|
|
// Translate the account from user space
|
|
|
|
@@ -1075,7 +1075,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BpfError>> {
|
|
|
|
|
let mut signers = Vec::new();
|
|
|
|
|
if signers_seeds_len > 0 {
|
|
|
|
|
let signers_seeds = translate_slice::<&[&[u8]]>(
|
|
|
|
@@ -1110,7 +1110,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
self.loader_id,
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
|
|
|
|
let signer = Pubkey::create_program_address(&seeds, program_id)
|
|
|
|
|
.map_err(SyscallError::BadSeeds)?;
|
|
|
|
|
signers.push(signer);
|
|
|
|
@@ -1121,7 +1121,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
instruction_addr: u64,
|
|
|
|
@@ -1130,7 +1130,7 @@ impl<'a> SyscallObject<BPFError> for SyscallInvokeSignedRust<'a> {
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
*result = call(
|
|
|
|
|
self,
|
|
|
|
@@ -1197,12 +1197,12 @@ pub struct SyscallInvokeSignedC<'a> {
|
|
|
|
|
loader_id: &'a Pubkey,
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
|
|
|
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
|
|
|
|
self.invoke_context
|
|
|
|
|
.try_borrow_mut()
|
|
|
|
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
|
|
|
|
}
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
|
|
|
|
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
|
|
|
|
self.invoke_context
|
|
|
|
|
.try_borrow()
|
|
|
|
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
|
|
|
@@ -1216,7 +1216,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
&self,
|
|
|
|
|
addr: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Instruction, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<Instruction, EbpfError<BpfError>> {
|
|
|
|
|
let ix_c = translate_type::<SolInstruction>(memory_mapping, addr, self.loader_id)?;
|
|
|
|
|
|
|
|
|
|
check_instruction_size(
|
|
|
|
@@ -1250,7 +1250,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
is_writable: meta_c.is_writable,
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<AccountMeta>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<AccountMeta>, EbpfError<BpfError>>>()?;
|
|
|
|
|
|
|
|
|
|
Ok(Instruction {
|
|
|
|
|
program_id: *program_id,
|
|
|
|
@@ -1266,7 +1266,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
account_infos_addr: u64,
|
|
|
|
|
account_infos_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
|
|
|
|
|
let invoke_context = self.invoke_context.borrow();
|
|
|
|
|
|
|
|
|
|
let account_infos = translate_slice::<SolAccountInfo>(
|
|
|
|
@@ -1281,7 +1281,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
.map(|account_info| {
|
|
|
|
|
translate_type::<Pubkey>(memory_mapping, account_info.key_addr, self.loader_id)
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
|
|
|
|
|
|
|
|
|
let translate = |account_info: &SolAccountInfo| {
|
|
|
|
|
// Translate the account from user space
|
|
|
|
@@ -1358,7 +1358,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<Vec<Pubkey>, EbpfError<BpfError>> {
|
|
|
|
|
if signers_seeds_len > 0 {
|
|
|
|
|
let signers_seeds = translate_slice::<SolSignerSeedC>(
|
|
|
|
|
memory_mapping,
|
|
|
|
@@ -1394,17 +1394,17 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
self.loader_id,
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
|
|
|
|
Pubkey::create_program_address(&seeds_bytes, program_id)
|
|
|
|
|
.map_err(|err| SyscallError::BadSeeds(err).into())
|
|
|
|
|
})
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?)
|
|
|
|
|
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?)
|
|
|
|
|
} else {
|
|
|
|
|
Ok(vec![])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
impl<'a> SyscallObject<BPFError> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
impl<'a> SyscallObject<BpfError> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
fn call(
|
|
|
|
|
&mut self,
|
|
|
|
|
instruction_addr: u64,
|
|
|
|
@@ -1413,7 +1413,7 @@ impl<'a> SyscallObject<BPFError> for SyscallInvokeSignedC<'a> {
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BPFError>>,
|
|
|
|
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
|
|
|
|
) {
|
|
|
|
|
*result = call(
|
|
|
|
|
self,
|
|
|
|
@@ -1434,9 +1434,9 @@ fn get_translated_accounts<'a, T, F>(
|
|
|
|
|
account_infos: &[T],
|
|
|
|
|
invoke_context: &Ref<&mut dyn InvokeContext>,
|
|
|
|
|
do_translate: F,
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BPFError>>
|
|
|
|
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>
|
|
|
|
|
where
|
|
|
|
|
F: Fn(&T) -> Result<TranslatedAccount<'a>, EbpfError<BPFError>>,
|
|
|
|
|
F: Fn(&T) -> Result<TranslatedAccount<'a>, EbpfError<BpfError>>,
|
|
|
|
|
{
|
|
|
|
|
let mut accounts = Vec::with_capacity(account_keys.len());
|
|
|
|
|
let mut refs = Vec::with_capacity(account_keys.len());
|
|
|
|
@@ -1490,7 +1490,7 @@ fn check_instruction_size(
|
|
|
|
|
num_accounts: usize,
|
|
|
|
|
data_len: usize,
|
|
|
|
|
invoke_context: &Ref<&mut dyn InvokeContext>,
|
|
|
|
|
) -> Result<(), EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<(), EbpfError<BpfError>> {
|
|
|
|
|
let size = num_accounts
|
|
|
|
|
.saturating_mul(size_of::<AccountMeta>())
|
|
|
|
|
.saturating_add(data_len);
|
|
|
|
@@ -1506,7 +1506,7 @@ fn check_instruction_size(
|
|
|
|
|
fn check_account_infos(
|
|
|
|
|
len: usize,
|
|
|
|
|
invoke_context: &Ref<&mut dyn InvokeContext>,
|
|
|
|
|
) -> Result<(), EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<(), EbpfError<BpfError>> {
|
|
|
|
|
if len * size_of::<Pubkey>()
|
|
|
|
|
> invoke_context
|
|
|
|
|
.get_bpf_compute_budget()
|
|
|
|
@@ -1523,7 +1523,7 @@ fn check_account_infos(
|
|
|
|
|
fn check_authorized_program(
|
|
|
|
|
program_id: &Pubkey,
|
|
|
|
|
instruction_data: &[u8],
|
|
|
|
|
) -> Result<(), EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<(), EbpfError<BpfError>> {
|
|
|
|
|
if native_loader::check_id(program_id)
|
|
|
|
|
|| bpf_loader::check_id(program_id)
|
|
|
|
|
|| bpf_loader_deprecated::check_id(program_id)
|
|
|
|
@@ -1539,7 +1539,7 @@ fn get_upgradeable_executable(
|
|
|
|
|
callee_program_id: &Pubkey,
|
|
|
|
|
program_account: &RefCell<Account>,
|
|
|
|
|
invoke_context: &Ref<&mut dyn InvokeContext>,
|
|
|
|
|
) -> Result<Option<(Pubkey, RefCell<Account>)>, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<Option<(Pubkey, RefCell<Account>)>, EbpfError<BpfError>> {
|
|
|
|
|
if program_account.borrow().owner == bpf_loader_upgradeable::id() {
|
|
|
|
|
match program_account.borrow().state() {
|
|
|
|
|
Ok(UpgradeableLoaderState::Program {
|
|
|
|
@@ -1579,7 +1579,7 @@ fn call<'a>(
|
|
|
|
|
signers_seeds_addr: u64,
|
|
|
|
|
signers_seeds_len: u64,
|
|
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
|
|
) -> Result<u64, EbpfError<BPFError>> {
|
|
|
|
|
) -> Result<u64, EbpfError<BpfError>> {
|
|
|
|
|
let (
|
|
|
|
|
message,
|
|
|
|
|
executables,
|
|
|
|
@@ -1854,7 +1854,7 @@ mod tests {
|
|
|
|
|
let translated_instruction =
|
|
|
|
|
translate_type::<Instruction>(&memory_mapping, 96, &bpf_loader::id()).unwrap();
|
|
|
|
|
assert_eq!(instruction, *translated_instruction);
|
|
|
|
|
memory_mapping.resize_region::<BPFError>(0, 1).unwrap();
|
|
|
|
|
memory_mapping.resize_region::<BpfError>(0, 1).unwrap();
|
|
|
|
|
assert!(translate_type::<Instruction>(&memory_mapping, 100, &bpf_loader::id()).is_err());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1992,7 +1992,7 @@ mod tests {
|
|
|
|
|
#[should_panic(expected = "UserError(SyscallError(Abort))")]
|
|
|
|
|
fn test_syscall_abort() {
|
|
|
|
|
let memory_mapping = MemoryMapping::new(vec![MemoryRegion::default()], &DEFAULT_CONFIG);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
SyscallAbort::call(
|
|
|
|
|
&mut SyscallAbort {},
|
|
|
|
|
0,
|
|
|
|
@@ -2030,7 +2030,7 @@ mod tests {
|
|
|
|
|
compute_meter: Some(compute_meter),
|
|
|
|
|
loader_id: &bpf_loader::id(),
|
|
|
|
|
};
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_panic.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2041,7 +2041,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
|
|
|
|
Err(EbpfError::UserError(BpfError::SyscallError(
|
|
|
|
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
|
|
|
|
))),
|
|
|
|
|
result
|
|
|
|
@@ -2051,7 +2051,7 @@ mod tests {
|
|
|
|
|
compute_meter: None,
|
|
|
|
|
loader_id: &bpf_loader::id(),
|
|
|
|
|
};
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_panic.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2092,7 +2092,7 @@ mod tests {
|
|
|
|
|
&DEFAULT_CONFIG,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2106,7 +2106,7 @@ mod tests {
|
|
|
|
|
assert_eq!(log.borrow().len(), 1);
|
|
|
|
|
assert_eq!(log.borrow()[0], "Program log: Gaggablaghblagh!");
|
|
|
|
|
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
101, // AccessViolation
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2117,7 +2117,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_access_violation!(result, 101, string.len() as u64);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64 * 2, // AccessViolation
|
|
|
|
@@ -2128,7 +2128,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_access_violation!(result, 100, string.len() as u64 * 2);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2139,7 +2139,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
|
|
|
|
Err(EbpfError::UserError(BpfError::SyscallError(
|
|
|
|
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
|
|
|
|
))),
|
|
|
|
|
result
|
|
|
|
@@ -2157,7 +2157,7 @@ mod tests {
|
|
|
|
|
logger,
|
|
|
|
|
loader_id: &bpf_loader::id(),
|
|
|
|
|
};
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2168,7 +2168,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
result.unwrap();
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log.call(
|
|
|
|
|
100,
|
|
|
|
|
string.len() as u64,
|
|
|
|
@@ -2179,7 +2179,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
|
|
|
|
Err(EbpfError::UserError(BpfError::SyscallError(
|
|
|
|
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
|
|
|
|
))),
|
|
|
|
|
result
|
|
|
|
@@ -2202,7 +2202,7 @@ mod tests {
|
|
|
|
|
};
|
|
|
|
|
let memory_mapping = MemoryMapping::new(vec![], &DEFAULT_CONFIG);
|
|
|
|
|
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_log_u64.call(1, 2, 3, 4, 5, &memory_mapping, &mut result);
|
|
|
|
|
result.unwrap();
|
|
|
|
|
|
|
|
|
@@ -2237,7 +2237,7 @@ mod tests {
|
|
|
|
|
&DEFAULT_CONFIG,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_pubkey.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
result.unwrap();
|
|
|
|
|
assert_eq!(log.borrow().len(), 1);
|
|
|
|
@@ -2245,7 +2245,7 @@ mod tests {
|
|
|
|
|
log.borrow()[0],
|
|
|
|
|
"Program log: MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN"
|
|
|
|
|
);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_pubkey.call(
|
|
|
|
|
101, // AccessViolation
|
|
|
|
|
32,
|
|
|
|
@@ -2256,10 +2256,10 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_access_violation!(result, 101, 32);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall_sol_pubkey.call(100, 32, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
|
|
|
|
Err(EbpfError::UserError(BpfError::SyscallError(
|
|
|
|
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
|
|
|
|
))),
|
|
|
|
|
result
|
|
|
|
@@ -2277,15 +2277,15 @@ mod tests {
|
|
|
|
|
);
|
|
|
|
|
let mut syscall = SyscallAllocFree {
|
|
|
|
|
aligned: true,
|
|
|
|
|
allocator: BPFAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
allocator: BpfAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
};
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_ne!(result.unwrap(), 0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(result.unwrap(), 0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(u64::MAX, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(result.unwrap(), 0);
|
|
|
|
|
}
|
|
|
|
@@ -2298,14 +2298,14 @@ mod tests {
|
|
|
|
|
);
|
|
|
|
|
let mut syscall = SyscallAllocFree {
|
|
|
|
|
aligned: false,
|
|
|
|
|
allocator: BPFAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
allocator: BpfAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
};
|
|
|
|
|
for _ in 0..100 {
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(1, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_ne!(result.unwrap(), 0);
|
|
|
|
|
}
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(result.unwrap(), 0);
|
|
|
|
|
}
|
|
|
|
@@ -2318,14 +2318,14 @@ mod tests {
|
|
|
|
|
);
|
|
|
|
|
let mut syscall = SyscallAllocFree {
|
|
|
|
|
aligned: true,
|
|
|
|
|
allocator: BPFAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
allocator: BpfAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
};
|
|
|
|
|
for _ in 0..12 {
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(1, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_ne!(result.unwrap(), 0);
|
|
|
|
|
}
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(result.unwrap(), 0);
|
|
|
|
|
}
|
|
|
|
@@ -2339,9 +2339,9 @@ mod tests {
|
|
|
|
|
);
|
|
|
|
|
let mut syscall = SyscallAllocFree {
|
|
|
|
|
aligned: true,
|
|
|
|
|
allocator: BPFAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
allocator: BpfAllocator::new(heap, MM_HEAP_START),
|
|
|
|
|
};
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(
|
|
|
|
|
size_of::<u8>() as u64,
|
|
|
|
|
0,
|
|
|
|
@@ -2428,13 +2428,13 @@ mod tests {
|
|
|
|
|
loader_id: &bpf_loader_deprecated::id(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(ro_va, ro_len, rw_va, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
result.unwrap();
|
|
|
|
|
|
|
|
|
|
let hash_local = hashv(&[bytes1.as_ref(), bytes2.as_ref()]).to_bytes();
|
|
|
|
|
assert_eq!(hash_result, hash_local);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(
|
|
|
|
|
ro_va - 1, // AccessViolation
|
|
|
|
|
ro_len,
|
|
|
|
@@ -2445,7 +2445,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_access_violation!(result, ro_va - 1, ro_len);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(
|
|
|
|
|
ro_va,
|
|
|
|
|
ro_len + 1, // AccessViolation
|
|
|
|
@@ -2456,7 +2456,7 @@ mod tests {
|
|
|
|
|
&mut result,
|
|
|
|
|
);
|
|
|
|
|
assert_access_violation!(result, ro_va, ro_len + 1);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BPFError>> = Ok(0);
|
|
|
|
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
|
|
|
|
syscall.call(
|
|
|
|
|
ro_va,
|
|
|
|
|
ro_len,
|
|
|
|
@@ -2470,7 +2470,7 @@ mod tests {
|
|
|
|
|
|
|
|
|
|
syscall.call(ro_va, ro_len, rw_va, 0, 0, &memory_mapping, &mut result);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
|
|
|
|
Err(EbpfError::UserError(BpfError::SyscallError(
|
|
|
|
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
|
|
|
|
))),
|
|
|
|
|
result
|
|
|
|
|