Files

55 lines
1.7 KiB
Rust

//! System call argument validation functions
use libk::task::{mem::ForeignPointer, thread::Thread};
use yggdrasil_abi::error::Error;
/// Validates a &T passed as an address
pub fn ref_const<'a, T: Sized>(addr: usize) -> Result<&'a T, Error> {
let proc = Thread::current();
let ptr = addr as *const T;
unsafe { ptr.validate_user_ptr(proc.address_space()) }
}
/// Validates a &mut T passed as an address
pub fn ref_mut<'a, T: Sized>(addr: usize) -> Result<&'a mut T, Error> {
let proc = Thread::current();
let ptr = addr as *mut T;
unsafe { ptr.validate_user_mut(proc.address_space()) }
}
/// Validates a &str passed as base address and length
pub fn str_ref<'a>(base: usize, len: usize) -> Result<&'a str, Error> {
if len == 0 {
// Ignore the base
return Ok("");
}
let slice = slice_ref(base, len)?;
if slice.contains(&0) {
log::warn!("User-supplied string contains NUL characters");
return Err(Error::InvalidArgument);
}
Ok(core::str::from_utf8(slice).unwrap())
}
/// Validates a &[T] passed as base address and element count
pub fn slice_ref<'a, T: Sized>(base: usize, count: usize) -> Result<&'a [T], Error> {
if count == 0 {
// Ignore the base
return Ok(&[]);
}
let proc = Thread::current();
let ptr = base as *const T;
unsafe { ptr.validate_user_slice(count, proc.address_space()) }
}
/// Validates a &mut [T] passed as base address and element count
pub fn slice_mut<'a, T: Sized>(base: usize, count: usize) -> Result<&'a mut [T], Error> {
if count == 0 {
// Ignore the base
return Ok(&mut []);
}
let proc = Thread::current();
let ptr = base as *mut T;
unsafe { ptr.validate_user_slice_mut(count, proc.address_space()) }
}