From 9e9ffedfc59cd89f4cdbd7984abbb2ac19ea9575 Mon Sep 17 00:00:00 2001 From: Plucky923 <107762234+Plucky923@users.noreply.github.com> Date: Mon, 9 Oct 2023 01:11:14 +0800 Subject: [PATCH] =?UTF-8?q?syscall:=20=E5=AE=8C=E5=96=84syscall=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=20(#387)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * syscall: 完善syscall代码 修改代码使这段代码可以使用语法糖。修改SYS_READ和SYS_WRITE的安全检查为userbuffer Signed-off-by: plucky * syscall: 修改SYS_READ和SYS_WRITE的权限检查为userbuffer Signed-off-by: plucky * syscall: 有不知道如何修改的错误 Signed-off-by: plucky * syscall: 修改SYS_READ和SYS_WRITE并编译通过 Signed-off-by: plucky --- kernel/src/arch/x86_64/syscall.rs | 6 ++- kernel/src/syscall/mod.rs | 66 ++++++++++--------------------- 2 files changed, 25 insertions(+), 47 deletions(-) diff --git a/kernel/src/arch/x86_64/syscall.rs b/kernel/src/arch/x86_64/syscall.rs index d64b17d2..3ea976bf 100644 --- a/kernel/src/arch/x86_64/syscall.rs +++ b/kernel/src/arch/x86_64/syscall.rs @@ -43,7 +43,11 @@ pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () { } _ => {} } - syscall_return!(Syscall::handle(syscall_num, &args, frame) as u64, frame); + syscall_return!( + Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize) + as u64, + frame + ); } /// 系统调用初始化 diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index b3bec251..53e7bc5f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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 { 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; }