diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 955020f..cbd828d 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -171,8 +171,9 @@ pub fn enlarge_heap(heap: &mut Heap) { } } -pub fn access_ok(from: usize, len: usize) -> bool { - from < PHYSICAL_MEMORY_OFFSET && (from + len) < PHYSICAL_MEMORY_OFFSET +/// Check whether the address range [addr, addr + len) is not in kernel space +pub fn access_ok(addr: usize, len: usize) -> bool { + addr < PHYSICAL_MEMORY_OFFSET && (addr + len) < PHYSICAL_MEMORY_OFFSET } #[naked] @@ -180,39 +181,19 @@ pub unsafe extern "C" fn read_user_fixup() -> usize { return 1; } -#[no_mangle] -pub fn copy_from_user_u8(addr: *const u8) -> Option { +pub fn copy_from_user(addr: *const T) -> Option { #[naked] #[inline(never)] #[link_section = ".text.copy_user"] - unsafe extern "C" fn read_user_u8(dst: *mut u8, src: *const u8) -> usize { + unsafe extern "C" fn read_user(dst: *mut T, src: *const T) -> usize { dst.copy_from_nonoverlapping(src, 1); 0 } - if !access_ok(addr as usize, size_of::()) { + if !access_ok(addr as usize, size_of::()) { return None; } - let mut dst: u8 = 0; - match unsafe { read_user_u8((&mut dst) as *mut u8, addr) } { - 0 => Some(dst), - _ => None, - } -} - -#[no_mangle] -pub fn copy_from_user_usize(addr: *const usize) -> Option { - #[naked] - #[inline(never)] - #[link_section = ".text.copy_user"] - unsafe extern "C" fn read_user_usize(dst: *mut usize, src: *const usize) -> usize { - dst.copy_from_nonoverlapping(src, 1); - 0 - } - if !access_ok(addr as usize, size_of::()) { - return None; - } - let mut dst: usize = 0; - match unsafe { read_user_usize((&mut dst) as *mut usize, addr) } { + let mut dst: T = unsafe { core::mem::uninitialized() }; + match unsafe { read_user(&mut dst, addr) } { 0 => Some(dst), _ => None, } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 1e5fe1e..cc4086d 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -10,7 +10,7 @@ use rcore_memory::VMError; use crate::arch::cpu; use crate::arch::interrupt::TrapFrame; use crate::arch::syscall::*; -use crate::memory::{copy_from_user_u8, copy_from_user_usize, MemorySet}; +use crate::memory::{copy_from_user, MemorySet}; use crate::process::*; use crate::sync::{Condvar, MutexGuard, SpinNoIrq}; use crate::thread; @@ -561,33 +561,25 @@ pub fn check_and_clone_cstr(user: *const u8) -> Result { let mut buffer = Vec::new(); for i in 0.. { let addr = unsafe { user.add(i) }; - if let Some(data) = copy_from_user_u8(addr) { - if data > 0 { - buffer.push(data); - } else { - break; - } - } else { - return Err(SysError::EFAULT); + let data = copy_from_user(addr).ok_or(SysError::EFAULT)?; + if data == 0 { + break; } + buffer.push(data); } - return String::from_utf8(buffer).map_err(|_| SysError::EFAULT); + String::from_utf8(buffer).map_err(|_| SysError::EFAULT) } pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, SysError> { let mut buffer = Vec::new(); for i in 0.. { let addr = unsafe { user.add(i) }; - if let Some(str_addr) = copy_from_user_usize(addr as *const usize) { - if str_addr > 0 { - let string = check_and_clone_cstr(str_addr as *const u8)?; - buffer.push(string); - } else { - break; - } - } else { - return Err(SysError::EFAULT); + let str_ptr = copy_from_user(addr).ok_or(SysError::EFAULT)?; + if str_ptr.is_null() { + break; } + let string = check_and_clone_cstr(str_ptr)?; + buffer.push(string); } - return Ok(buffer); + Ok(buffer) }