2022-07-16 10:33:57 -07:00
|
|
|
use {super::*, crate::declare_syscall};
|
|
|
|
|
2022-10-06 11:31:58 -07:00
|
|
|
fn mem_op_consume(invoke_context: &mut InvokeContext, n: u64) -> Result<(), EbpfError> {
|
2022-07-16 10:33:57 -07:00
|
|
|
let compute_budget = invoke_context.get_compute_budget();
|
|
|
|
let cost = compute_budget
|
|
|
|
.mem_op_base_cost
|
|
|
|
.max(n.saturating_div(compute_budget.cpi_bytes_per_unit));
|
2022-11-15 06:21:11 -08:00
|
|
|
consume_compute_meter(invoke_context, cost)
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
declare_syscall!(
|
|
|
|
/// memcpy
|
|
|
|
SyscallMemcpy,
|
2022-10-06 11:31:58 -07:00
|
|
|
fn inner_call(
|
|
|
|
invoke_context: &mut InvokeContext,
|
2022-07-16 10:33:57 -07:00
|
|
|
dst_addr: u64,
|
|
|
|
src_addr: u64,
|
|
|
|
n: u64,
|
|
|
|
_arg4: u64,
|
|
|
|
_arg5: u64,
|
|
|
|
memory_mapping: &mut MemoryMapping,
|
2022-10-06 11:31:58 -07:00
|
|
|
) -> Result<u64, EbpfError> {
|
|
|
|
mem_op_consume(invoke_context, n)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
|
2022-10-27 10:11:18 -07:00
|
|
|
if !is_nonoverlapping(src_addr, n, dst_addr, n) {
|
2022-10-06 11:31:58 -07:00
|
|
|
return Err(SyscallError::CopyOverlapping.into());
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
|
2022-10-06 11:31:58 -07:00
|
|
|
let dst_ptr = translate_slice_mut::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
dst_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?
|
2022-07-16 10:33:57 -07:00
|
|
|
.as_mut_ptr();
|
2022-10-06 11:31:58 -07:00
|
|
|
let src_ptr = translate_slice::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
src_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?
|
2022-07-16 10:33:57 -07:00
|
|
|
.as_ptr();
|
2022-12-22 00:07:08 -08:00
|
|
|
if !is_nonoverlapping(src_ptr as usize, n as usize, dst_ptr as usize, n as usize) {
|
2022-07-16 10:33:57 -07:00
|
|
|
unsafe {
|
|
|
|
std::ptr::copy(src_ptr, dst_ptr, n as usize);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
unsafe {
|
|
|
|
std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, n as usize);
|
|
|
|
}
|
|
|
|
}
|
2022-10-06 11:31:58 -07:00
|
|
|
Ok(0)
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
declare_syscall!(
|
|
|
|
/// memmove
|
|
|
|
SyscallMemmove,
|
2022-10-06 11:31:58 -07:00
|
|
|
fn inner_call(
|
|
|
|
invoke_context: &mut InvokeContext,
|
2022-07-16 10:33:57 -07:00
|
|
|
dst_addr: u64,
|
|
|
|
src_addr: u64,
|
|
|
|
n: u64,
|
|
|
|
_arg4: u64,
|
|
|
|
_arg5: u64,
|
|
|
|
memory_mapping: &mut MemoryMapping,
|
2022-10-06 11:31:58 -07:00
|
|
|
) -> Result<u64, EbpfError> {
|
|
|
|
mem_op_consume(invoke_context, n)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
|
2022-10-06 11:31:58 -07:00
|
|
|
let dst = translate_slice_mut::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
dst_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?;
|
|
|
|
let src = translate_slice::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
src_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
unsafe {
|
|
|
|
std::ptr::copy(src.as_ptr(), dst.as_mut_ptr(), n as usize);
|
|
|
|
}
|
2022-10-06 11:31:58 -07:00
|
|
|
Ok(0)
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
declare_syscall!(
|
|
|
|
/// memcmp
|
|
|
|
SyscallMemcmp,
|
2022-10-06 11:31:58 -07:00
|
|
|
fn inner_call(
|
|
|
|
invoke_context: &mut InvokeContext,
|
2022-07-16 10:33:57 -07:00
|
|
|
s1_addr: u64,
|
|
|
|
s2_addr: u64,
|
|
|
|
n: u64,
|
|
|
|
cmp_result_addr: u64,
|
|
|
|
_arg5: u64,
|
|
|
|
memory_mapping: &mut MemoryMapping,
|
2022-10-06 11:31:58 -07:00
|
|
|
) -> Result<u64, EbpfError> {
|
|
|
|
mem_op_consume(invoke_context, n)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
|
2022-10-06 11:31:58 -07:00
|
|
|
let s1 = translate_slice::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
s1_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?;
|
|
|
|
let s2 = translate_slice::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
s2_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?;
|
|
|
|
let cmp_result = translate_type_mut::<i32>(
|
|
|
|
memory_mapping,
|
|
|
|
cmp_result_addr,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
let mut i = 0;
|
|
|
|
while i < n as usize {
|
2022-10-06 11:31:58 -07:00
|
|
|
let a = *s1.get(i).ok_or(SyscallError::InvalidLength)?;
|
|
|
|
let b = *s2.get(i).ok_or(SyscallError::InvalidLength)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
if a != b {
|
2022-11-23 01:42:59 -08:00
|
|
|
*cmp_result = (a as i32).saturating_sub(b as i32);
|
2022-10-06 11:31:58 -07:00
|
|
|
return Ok(0);
|
2022-07-16 10:33:57 -07:00
|
|
|
};
|
|
|
|
i = i.saturating_add(1);
|
|
|
|
}
|
|
|
|
*cmp_result = 0;
|
2022-10-06 11:31:58 -07:00
|
|
|
Ok(0)
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
declare_syscall!(
|
|
|
|
/// memset
|
|
|
|
SyscallMemset,
|
2022-10-06 11:31:58 -07:00
|
|
|
fn inner_call(
|
|
|
|
invoke_context: &mut InvokeContext,
|
2022-07-16 10:33:57 -07:00
|
|
|
s_addr: u64,
|
|
|
|
c: u64,
|
|
|
|
n: u64,
|
|
|
|
_arg4: u64,
|
|
|
|
_arg5: u64,
|
|
|
|
memory_mapping: &mut MemoryMapping,
|
2022-10-06 11:31:58 -07:00
|
|
|
) -> Result<u64, EbpfError> {
|
|
|
|
mem_op_consume(invoke_context, n)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
|
2022-10-06 11:31:58 -07:00
|
|
|
let s = translate_slice_mut::<u8>(
|
|
|
|
memory_mapping,
|
|
|
|
s_addr,
|
|
|
|
n,
|
|
|
|
invoke_context.get_check_aligned(),
|
|
|
|
invoke_context.get_check_size(),
|
|
|
|
)?;
|
2022-07-16 10:33:57 -07:00
|
|
|
for val in s.iter_mut().take(n as usize) {
|
|
|
|
*val = c as u8;
|
|
|
|
}
|
2022-10-06 11:31:58 -07:00
|
|
|
Ok(0)
|
2022-07-16 10:33:57 -07:00
|
|
|
}
|
|
|
|
);
|