diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index eee87ea..f5b3402 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -23,9 +23,11 @@ kernel-macros = { path = "macros" } cortex-a = { version = "6.x.x" } [features] +default = ["aggressive_syscall"] pl011 = [] pl031 = [] verbose = [] +aggressive_syscall = [] mach_qemu = ["pl011", "pl031"] mach_orangepi3 = [] diff --git a/kernel/src/syscall/arg.rs b/kernel/src/syscall/arg.rs index 72a377d..caedd58 100644 --- a/kernel/src/syscall/arg.rs +++ b/kernel/src/syscall/arg.rs @@ -4,6 +4,24 @@ use crate::mem; use core::mem::size_of; use libsys::error::Errno; +// TODO _mut() versions checking whether pages are actually writable + +macro_rules! invalid_memory { + ($($args:tt)+) => { + warnln!($($args)+); + #[cfg(feature = "aggressive_syscall")] + { + use libsys::signal::Signal; + use crate::proc::Thread; + + let thread = Thread::current(); + let proc = thread.owner().unwrap(); + proc.enter_fault_signal(thread, Signal::SegmentationFault); + } + return Err(Errno::InvalidArgument); + } +} + fn translate(virt: usize) -> Option { let mut res: usize; unsafe { @@ -33,23 +51,21 @@ pub fn validate_user_ptr_struct_option<'a, T>(base: usize) -> Result(base: usize, len: usize) -> Result<&'a mut [u8], Errno> { if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET { - warnln!( + invalid_memory!( "User region refers to kernel memory: base={:#x}, len={:#x}", base, len ); - return Err(Errno::InvalidArgument); } for i in (base / mem::PAGE_SIZE)..((base + len + mem::PAGE_SIZE - 1) / mem::PAGE_SIZE) { if translate(i * mem::PAGE_SIZE).is_none() { - warnln!( + invalid_memory!( "User region refers to unmapped memory: base={:#x}, len={:#x} (page {:#x})", base, len, i * mem::PAGE_SIZE ); - return Err(Errno::InvalidArgument); } } @@ -77,49 +93,3 @@ pub fn validate_user_str<'a>(base: usize, len: usize) -> Result<&'a str, Errno> Errno::InvalidArgument }) } -// if base > mem::KERNEL_OFFSET { -// warnln!("User string refers to kernel memory: base={:#x}", base); -// return Err(Errno::InvalidArgument); -// } -// -// let base_ptr = base as *const u8; -// let mut len = 0; -// let mut page_valid = false; -// loop { -// if len == limit { -// warnln!("User string exceeded limit: base={:#x}", base); -// return Err(Errno::InvalidArgument); -// } -// -// if (base + len) % mem::PAGE_SIZE == 0 { -// page_valid = false; -// } -// -// if !page_valid && translate((base + len) & !0xFFF).is_none() { -// warnln!( -// "User string refers to unmapped memory: base={:#x}, off={:#x}", -// base, -// len -// ); -// return Err(Errno::InvalidArgument); -// } -// -// page_valid = true; -// -// let byte = unsafe { *base_ptr.add(len) }; -// if byte == 0 { -// break; -// } -// -// len += 1; -// } -// -// let slice = unsafe { core::slice::from_raw_parts(base_ptr, len) }; -// core::str::from_utf8(slice).map_err(|_| { -// warnln!( -// "User string contains invalid UTF-8 characters: base={:#x}", -// base -// ); -// Errno::InvalidArgument -// }) -// }