feature: "aggressive" syscall memory checking

This commit is contained in:
Mark Poliakov 2021-11-21 12:36:20 +02:00
parent bf1a215730
commit 1820009dee
2 changed files with 22 additions and 50 deletions

View File

@ -23,9 +23,11 @@ kernel-macros = { path = "macros" }
cortex-a = { version = "6.x.x" } cortex-a = { version = "6.x.x" }
[features] [features]
default = ["aggressive_syscall"]
pl011 = [] pl011 = []
pl031 = [] pl031 = []
verbose = [] verbose = []
aggressive_syscall = []
mach_qemu = ["pl011", "pl031"] mach_qemu = ["pl011", "pl031"]
mach_orangepi3 = [] mach_orangepi3 = []

View File

@ -4,6 +4,24 @@ use crate::mem;
use core::mem::size_of; use core::mem::size_of;
use libsys::error::Errno; 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<usize> { fn translate(virt: usize) -> Option<usize> {
let mut res: usize; let mut res: usize;
unsafe { unsafe {
@ -33,23 +51,21 @@ pub fn validate_user_ptr_struct_option<'a, T>(base: usize) -> Result<Option<&'a
/// Unwraps an user buffer reference /// Unwraps an user buffer reference
pub fn validate_user_ptr<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Errno> { pub fn validate_user_ptr<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Errno> {
if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET { if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET {
warnln!( invalid_memory!(
"User region refers to kernel memory: base={:#x}, len={:#x}", "User region refers to kernel memory: base={:#x}, len={:#x}",
base, base,
len len
); );
return Err(Errno::InvalidArgument);
} }
for i in (base / mem::PAGE_SIZE)..((base + len + mem::PAGE_SIZE - 1) / mem::PAGE_SIZE) { for i in (base / mem::PAGE_SIZE)..((base + len + mem::PAGE_SIZE - 1) / mem::PAGE_SIZE) {
if translate(i * mem::PAGE_SIZE).is_none() { if translate(i * mem::PAGE_SIZE).is_none() {
warnln!( invalid_memory!(
"User region refers to unmapped memory: base={:#x}, len={:#x} (page {:#x})", "User region refers to unmapped memory: base={:#x}, len={:#x} (page {:#x})",
base, base,
len, len,
i * mem::PAGE_SIZE 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 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
// })
// }