|
@@ -26,7 +26,7 @@ use crate::{
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-use self::user_access::UserBufferWriter;
|
|
|
+use self::user_access::{UserBufferReader, UserBufferWriter};
|
|
|
|
|
|
pub mod user_access;
|
|
|
|
|
@@ -406,7 +406,11 @@ impl Syscall {
|
|
|
///
|
|
|
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
|
|
|
/// 并且,对于用户态传入的指针参数,需要在本函数内进行越界检查,防止访问到内核空间。
|
|
|
- pub fn handle(syscall_num: usize, args: &[usize], frame: &mut TrapFrame) -> usize {
|
|
|
+ pub fn handle(
|
|
|
+ syscall_num: usize,
|
|
|
+ args: &[usize],
|
|
|
+ frame: &mut TrapFrame,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
let r = match syscall_num {
|
|
|
SYS_PUT_STRING => {
|
|
|
Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32)
|
|
@@ -437,40 +441,24 @@ impl Syscall {
|
|
|
let fd = args[0] as i32;
|
|
|
let buf_vaddr = args[1];
|
|
|
let len = args[2];
|
|
|
- let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr);
|
|
|
- // 判断缓冲区是否来自用户态,进行权限校验
|
|
|
- let res = if frame.from_user() && verify_area(virt_addr, len as usize).is_err() {
|
|
|
- // 来自用户态,而buffer在内核态,这样的操作不被允许
|
|
|
- Err(SystemError::EPERM)
|
|
|
- } else {
|
|
|
- let buf: &mut [u8] = unsafe {
|
|
|
- core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len)
|
|
|
- };
|
|
|
+ let from_user = frame.from_user();
|
|
|
+ let mut user_buffer_writer =
|
|
|
+ UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;
|
|
|
|
|
|
- Self::read(fd, buf)
|
|
|
- };
|
|
|
- // kdebug!("sys read, fd: {}, len: {}, res: {:?}", fd, len, res);
|
|
|
+ let user_buf = user_buffer_writer.buffer(0)?;
|
|
|
+ let res = Self::read(fd, user_buf);
|
|
|
res
|
|
|
}
|
|
|
SYS_WRITE => {
|
|
|
let fd = args[0] as i32;
|
|
|
let buf_vaddr = args[1];
|
|
|
let len = args[2];
|
|
|
- let virt_addr = VirtAddr::new(buf_vaddr);
|
|
|
- // 判断缓冲区是否来自用户态,进行权限校验
|
|
|
- let res = if frame.from_user() && verify_area(virt_addr, len as usize).is_err() {
|
|
|
- // 来自用户态,而buffer在内核态,这样的操作不被允许
|
|
|
- Err(SystemError::EPERM)
|
|
|
- } else {
|
|
|
- let buf: &[u8] = unsafe {
|
|
|
- core::slice::from_raw_parts::<'static, u8>(buf_vaddr as *const u8, len)
|
|
|
- };
|
|
|
-
|
|
|
- Self::write(fd, buf)
|
|
|
- };
|
|
|
-
|
|
|
- // kdebug!("sys write, fd: {}, len: {}, res: {:?}", fd, len, res);
|
|
|
+ let from_user = frame.from_user();
|
|
|
+ let user_buffer_reader =
|
|
|
+ UserBufferReader::new(buf_vaddr as *const u8, len, from_user)?;
|
|
|
|
|
|
+ let user_buf = user_buffer_reader.read_from_user(0)?;
|
|
|
+ let res = Self::write(fd, user_buf);
|
|
|
res
|
|
|
}
|
|
|
|
|
@@ -485,17 +473,9 @@ impl Syscall {
|
|
|
SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
|
|
|
SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
|
|
|
_ => Err(SystemError::EINVAL),
|
|
|
- };
|
|
|
+ }?;
|
|
|
|
|
|
- let res = if w.is_err() {
|
|
|
- Err(w.unwrap_err())
|
|
|
- } else {
|
|
|
- let w = w.unwrap();
|
|
|
- Self::lseek(fd, w)
|
|
|
- };
|
|
|
- // kdebug!("sys lseek, fd: {}, offset: {}, whence: {}, res: {:?}", fd, offset, whence, res);
|
|
|
-
|
|
|
- res
|
|
|
+ Self::lseek(fd, w)
|
|
|
}
|
|
|
|
|
|
SYS_FORK => Self::fork(frame),
|
|
@@ -539,12 +519,8 @@ impl Syscall {
|
|
|
return Ok(dest_path);
|
|
|
};
|
|
|
|
|
|
- let r: Result<&str, SystemError> = chdir_check(args[0]);
|
|
|
- if r.is_err() {
|
|
|
- Err(r.unwrap_err())
|
|
|
- } else {
|
|
|
- Self::chdir(r.unwrap())
|
|
|
- }
|
|
|
+ let r = chdir_check(args[0])?;
|
|
|
+ Self::chdir(r)
|
|
|
}
|
|
|
|
|
|
SYS_GET_DENTS => {
|
|
@@ -984,8 +960,6 @@ impl Syscall {
|
|
|
|
|
|
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
|
|
};
|
|
|
-
|
|
|
- let r = r.unwrap_or_else(|e| e.to_posix_errno() as usize);
|
|
|
return r;
|
|
|
}
|
|
|
|