syscall: 完善syscall代码 (#387)

* syscall: 完善syscall代码

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

Signed-off-by: plucky <m202372036@hust.edu.cn>

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

Signed-off-by: plucky <m202372036@hust.edu.cn>

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

Signed-off-by: plucky <m202372036@hust.edu.cn>

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

Signed-off-by: plucky <m202372036@hust.edu.cn>
This commit is contained in:
Plucky923 2023-10-09 01:11:14 +08:00 committed by GitHub
parent 865f4ba4cd
commit 9e9ffedfc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 47 deletions

View File

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

View File

@ -26,7 +26,7 @@ use crate::{
}, },
}; };
use self::user_access::UserBufferWriter; use self::user_access::{UserBufferReader, UserBufferWriter};
pub mod user_access; 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 { let r = match syscall_num {
SYS_PUT_STRING => { SYS_PUT_STRING => {
Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32) 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 fd = args[0] as i32;
let buf_vaddr = args[1]; let buf_vaddr = args[1];
let len = args[2]; let len = args[2];
let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr); let from_user = frame.from_user();
// 判断缓冲区是否来自用户态,进行权限校验 let mut user_buffer_writer =
let res = if frame.from_user() && verify_area(virt_addr, len as usize).is_err() { UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;
// 来自用户态而buffer在内核态这样的操作不被允许
Err(SystemError::EPERM)
} else {
let buf: &mut [u8] = unsafe {
core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len)
};
Self::read(fd, buf) let user_buf = user_buffer_writer.buffer(0)?;
}; let res = Self::read(fd, user_buf);
// kdebug!("sys read, fd: {}, len: {}, res: {:?}", fd, len, res);
res res
} }
SYS_WRITE => { SYS_WRITE => {
let fd = args[0] as i32; let fd = args[0] as i32;
let buf_vaddr = args[1]; let buf_vaddr = args[1];
let len = args[2]; let len = args[2];
let virt_addr = VirtAddr::new(buf_vaddr); let from_user = frame.from_user();
// 判断缓冲区是否来自用户态,进行权限校验 let user_buffer_reader =
let res = if frame.from_user() && verify_area(virt_addr, len as usize).is_err() { UserBufferReader::new(buf_vaddr as *const u8, len, from_user)?;
// 来自用户态而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 user_buf = user_buffer_reader.read_from_user(0)?;
let res = Self::write(fd, user_buf);
res res
} }
@ -485,17 +473,9 @@ impl Syscall {
SEEK_END => Ok(SeekFrom::SeekEnd(offset)), SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
SEEK_MAX => Ok(SeekFrom::SeekEnd(0)), SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
_ => Err(SystemError::EINVAL), _ => Err(SystemError::EINVAL),
}; }?;
let res = if w.is_err() {
Err(w.unwrap_err())
} else {
let w = w.unwrap();
Self::lseek(fd, w) Self::lseek(fd, w)
};
// kdebug!("sys lseek, fd: {}, offset: {}, whence: {}, res: {:?}", fd, offset, whence, res);
res
} }
SYS_FORK => Self::fork(frame), SYS_FORK => Self::fork(frame),
@ -539,12 +519,8 @@ impl Syscall {
return Ok(dest_path); return Ok(dest_path);
}; };
let r: Result<&str, SystemError> = chdir_check(args[0]); let r = chdir_check(args[0])?;
if r.is_err() { Self::chdir(r)
Err(r.unwrap_err())
} else {
Self::chdir(r.unwrap())
}
} }
SYS_GET_DENTS => { SYS_GET_DENTS => {
@ -984,8 +960,6 @@ impl Syscall {
_ => panic!("Unsupported syscall ID: {}", syscall_num), _ => panic!("Unsupported syscall ID: {}", syscall_num),
}; };
let r = r.unwrap_or_else(|e| e.to_posix_errno() as usize);
return r; return r;
} }