simplify copy_from_user

master
WangRunji 6 years ago
parent 8b07e7d31c
commit 9dec0bbda5

@ -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<u8> {
pub fn copy_from_user<T>(addr: *const T) -> Option<T> {
#[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<T>(dst: *mut T, src: *const T) -> usize {
dst.copy_from_nonoverlapping(src, 1);
0
}
if !access_ok(addr as usize, size_of::<u8>()) {
if !access_ok(addr as usize, size_of::<T>()) {
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<usize> {
#[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::<usize>()) {
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,
}

@ -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<String, SysError> {
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 {
let data = copy_from_user(addr).ok_or(SysError::EFAULT)?;
if data == 0 {
break;
}
} else {
return Err(SysError::EFAULT);
}
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<Vec<String>, 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 {
let str_ptr = copy_from_user(addr).ok_or(SysError::EFAULT)?;
if str_ptr.is_null() {
break;
}
} else {
return Err(SysError::EFAULT);
}
let string = check_and_clone_cstr(str_ptr)?;
buffer.push(string);
}
return Ok(buffer);
Ok(buffer)
}

Loading…
Cancel
Save