From f5df0e79c67a9508bc6a50fccded9dec78e7ed9d Mon Sep 17 00:00:00 2001 From: LoGin Date: Mon, 28 Aug 2023 15:29:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3userbufferwriter=E7=9A=84?= =?UTF-8?q?=E9=95=BF=E5=BA=A6=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E5=A4=8Dgettimeofday=E7=9A=84pagefault?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#349)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 解决userbufferwriter的长度错误问题,并修复gettimeofday的pagefault问题 --- kernel/src/syscall/mod.rs | 30 ++++------------------------ kernel/src/syscall/user_access.rs | 12 ++--------- kernel/src/time/syscall.rs | 33 ++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 48 deletions(-) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index ee27caa9..c42fe48d 100644 --- a/kernel/src/syscall/mod.rs +++ b/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::(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::(), true) { - Err(e) => Err(e), - Ok(_) => { - match UserBufferWriter::new( - timezone_ptr, - core::mem::size_of::(), - 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]); diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index 4a0897c9..abd5fbb8 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -258,19 +258,11 @@ impl<'a> UserBufferWriter<'a> { /// @return 构造成功返回UserbufferWriter实例,否则返回错误码 /// pub fn new(addr: *mut U, len: usize, from_user: bool) -> Result { - if from_user - && verify_area( - VirtAddr::new(addr as usize), - (len * core::mem::size_of::()) 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::()) - }, + buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) }, }); } diff --git a/kernel/src/time/syscall.rs b/kernel/src/time/syscall.rs index 15cfa014..4404fd1b 100644 --- a/kernel/src/time/syscall.rs +++ b/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::(tv, core::mem::size_of::(), true)?; + + let tz_buf = if timezone.is_null() { + None + } else { + Some(UserBufferWriter::new::( + timezone, + core::mem::size_of::(), + true, + )?) + }; + let posix_time = do_gettimeofday(); - unsafe { - (*tv).tv_sec = posix_time.tv_sec; - (*tv).tv_usec = posix_time.tv_usec; + + 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)?; } - if !timezone.is_null() { - unsafe { - *timezone = SYS_TIMEZONE; - } - } - // kdebug!("exit sys_do_gettimeofday"); return Ok(0); } }