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

* 解决userbufferwriter的长度错误问题,并修复gettimeofday的pagefault问题
This commit is contained in:
LoGin 2023-08-28 15:29:00 +08:00 committed by GitHub
parent ddb9d91712
commit f5df0e79c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 48 deletions

View File

@ -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)
}
}
}
}
}
}
SYS_MMAP => {
let len = page_align_up(args[1]);

View File

@ -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) },
});
}

View File

@ -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;
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);
}
}