Browse Source

syscall: 完善syscall代码 (#387)

* syscall: 完善syscall代码

修改代码使这段代码可以使用语法糖。修改SYS_READ和SYS_WRITE的安全检查为userbuffer

Signed-off-by: plucky <[email protected]>

* syscall: 修改SYS_READ和SYS_WRITE的权限检查为userbuffer

Signed-off-by: plucky <[email protected]>

* syscall: 有不知道如何修改的错误

Signed-off-by: plucky <[email protected]>

* syscall: 修改SYS_READ和SYS_WRITE并编译通过

Signed-off-by: plucky <[email protected]>
Plucky923 1 year ago
parent
commit
9e9ffedfc5
2 changed files with 25 additions and 47 deletions
  1. 5 1
      kernel/src/arch/x86_64/syscall.rs
  2. 20 46
      kernel/src/syscall/mod.rs

+ 5 - 1
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
+    );
 }
 
 /// 系统调用初始化

+ 20 - 46
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<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;
     }