Browse Source

解决userbufferwriter的长度错误问题,并修复gettimeofday的pagefault问题 (#349)

* 解决userbufferwriter的长度错误问题,并修复gettimeofday的pagefault问题
LoGin 1 year ago
parent
commit
f5df0e79c6
3 changed files with 27 additions and 48 deletions
  1. 4 26
      kernel/src/syscall/mod.rs
  2. 2 10
      kernel/src/syscall/user_access.rs
  3. 21 12
      kernel/src/time/syscall.rs

+ 4 - 26
kernel/src/syscall/mod.rs

@@ -435,7 +435,7 @@ impl Syscall {
                 let fd = args[0] as i32;
                 let buf_vaddr = args[1];
                 let len = args[2];
-                let virt_addr = VirtAddr::new(buf_vaddr);
+                let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr);
                 // 判断缓冲区是否来自用户态,进行权限校验
                 let res = if from_user && verify_area(virt_addr, len as usize).is_err() {
                     // 来自用户态,而buffer在内核态,这样的操作不被允许
@@ -545,7 +545,7 @@ impl Syscall {
                 let fd = args[0] as i32;
                 let buf_vaddr = args[1];
                 let len = args[2];
-                let virt_addr = VirtAddr::new(buf_vaddr);
+                let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr);
                 // 判断缓冲区是否来自用户态,进行权限校验
                 let res = if from_user && verify_area(virt_addr, len as usize).is_err() {
                     // 来自用户态,而buffer在内核态,这样的操作不被允许
@@ -653,11 +653,7 @@ impl Syscall {
             SYS_CLOCK => Self::clock(),
             SYS_PIPE => {
                 let pipefd = args[0] as *mut c_int;
-                match UserBufferWriter::new(
-                    pipefd,
-                    core::mem::size_of::<[c_int; 2]>() as usize,
-                    from_user,
-                ) {
+                match UserBufferWriter::new(pipefd, core::mem::size_of::<[c_int; 2]>(), from_user) {
                     Err(e) => Err(e),
                     Ok(mut user_buffer) => match user_buffer.buffer::<i32>(0) {
                         Err(e) => Err(e),
@@ -884,25 +880,7 @@ impl Syscall {
             SYS_GETTIMEOFDAY => {
                 let timeval = args[0] as *mut PosixTimeval;
                 let timezone_ptr = args[1] as *mut PosixTimeZone;
-                match UserBufferWriter::new(timeval, core::mem::size_of::<PosixTimeval>(), true) {
-                    Err(e) => Err(e),
-                    Ok(_) => {
-                        match UserBufferWriter::new(
-                            timezone_ptr,
-                            core::mem::size_of::<PosixTimeZone>(),
-                            true,
-                        ) {
-                            Err(e) => Err(e),
-                            Ok(_) => {
-                                if !timeval.is_null() {
-                                    Self::gettimeofday(timeval, timezone_ptr)
-                                } else {
-                                    Err(SystemError::EFAULT)
-                                }
-                            }
-                        }
-                    }
-                }
+                Self::gettimeofday(timeval, timezone_ptr)
             }
             SYS_MMAP => {
                 let len = page_align_up(args[1]);

+ 2 - 10
kernel/src/syscall/user_access.rs

@@ -258,19 +258,11 @@ impl<'a> UserBufferWriter<'a> {
     /// @return 构造成功返回UserbufferWriter实例,否则返回错误码
     ///
     pub fn new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError> {
-        if from_user
-            && verify_area(
-                VirtAddr::new(addr as usize),
-                (len * core::mem::size_of::<U>()) as usize,
-            )
-            .is_err()
-        {
+        if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() {
             return Err(SystemError::EFAULT);
         }
         return Ok(Self {
-            buffer: unsafe {
-                core::slice::from_raw_parts_mut(addr as *mut u8, len * core::mem::size_of::<U>())
-            },
+            buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) },
         });
     }
 

+ 21 - 12
kernel/src/time/syscall.rs

@@ -4,7 +4,7 @@ use core::{
 };
 
 use crate::{
-    syscall::{Syscall, SystemError},
+    syscall::{user_access::UserBufferWriter, Syscall, SystemError},
     time::{sleep::nanosleep, TimeSpec},
 };
 
@@ -14,14 +14,14 @@ pub type PosixTimeT = c_longlong;
 pub type PosixSusecondsT = c_int;
 
 #[repr(C)]
-#[derive(Default, Debug)]
+#[derive(Default, Debug, Copy, Clone)]
 pub struct PosixTimeval {
     pub tv_sec: PosixTimeT,
     pub tv_usec: PosixSusecondsT,
 }
 
 #[repr(C)]
-#[derive(Default, Debug)]
+#[derive(Default, Debug, Copy, Clone)]
 /// 当前时区信息
 pub struct PosixTimeZone {
     /// 格林尼治相对于当前时区相差的分钟数
@@ -85,18 +85,27 @@ impl Syscall {
         if tv == null_mut() {
             return Err(SystemError::EFAULT);
         }
+        let mut tv_buf =
+            UserBufferWriter::new::<PosixTimeval>(tv, core::mem::size_of::<PosixTimeval>(), true)?;
+
+        let tz_buf = if timezone.is_null() {
+            None
+        } else {
+            Some(UserBufferWriter::new::<PosixTimeZone>(
+                timezone,
+                core::mem::size_of::<PosixTimeZone>(),
+                true,
+            )?)
+        };
+
         let posix_time = do_gettimeofday();
-        unsafe {
-            (*tv).tv_sec = posix_time.tv_sec;
-            (*tv).tv_usec = posix_time.tv_usec;
-        }
 
-        if !timezone.is_null() {
-            unsafe {
-                *timezone = SYS_TIMEZONE;
-            }
+        tv_buf.copy_one_to_user(&posix_time, 0)?;
+
+        if let Some(mut tz_buf) = tz_buf {
+            tz_buf.copy_one_to_user(&SYS_TIMEZONE, 0)?;
         }
-        // kdebug!("exit sys_do_gettimeofday");
+
         return Ok(0);
     }
 }