|
@@ -7,16 +7,17 @@ use num_traits::{FromPrimitive, ToPrimitive};
|
|
|
|
|
|
use crate::{
|
|
|
arch::{cpu::cpu_reset, MMArch},
|
|
|
+ filesystem::syscall::PosixKstat,
|
|
|
filesystem::vfs::{
|
|
|
file::FileMode,
|
|
|
syscall::{SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET},
|
|
|
MAX_PATHLEN,
|
|
|
},
|
|
|
- include::bindings::bindings::{pid_t, verify_area, PAGE_2M_SIZE, PAGE_4K_SIZE},
|
|
|
+ include::bindings::bindings::{pid_t, PAGE_2M_SIZE, PAGE_4K_SIZE},
|
|
|
io::SeekFrom,
|
|
|
kinfo,
|
|
|
libs::align::page_align_up,
|
|
|
- mm::{MemoryManagementArch, VirtAddr},
|
|
|
+ mm::{verify_area, MemoryManagementArch, VirtAddr},
|
|
|
net::syscall::SockAddr,
|
|
|
time::{
|
|
|
syscall::{PosixTimeZone, PosixTimeval},
|
|
@@ -364,6 +365,8 @@ pub const SYS_MMAP: usize = 44;
|
|
|
pub const SYS_MUNMAP: usize = 45;
|
|
|
pub const SYS_MPROTECT: usize = 46;
|
|
|
|
|
|
+pub const SYS_FSTAT: usize = 47;
|
|
|
+
|
|
|
#[derive(Debug)]
|
|
|
pub struct Syscall;
|
|
|
|
|
@@ -421,9 +424,9 @@ 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 res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
|
|
|
+ let res = if from_user && verify_area(virt_addr, len as usize).is_err() {
|
|
|
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
|
|
Err(SystemError::EPERM)
|
|
|
} else {
|
|
@@ -439,9 +442,9 @@ 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 res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
|
|
|
+ let res = if from_user && verify_area(virt_addr, len as usize).is_err() {
|
|
|
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
|
|
Err(SystemError::EPERM)
|
|
|
} else {
|
|
@@ -496,10 +499,10 @@ impl Syscall {
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
|
let path_ptr = arg0 as *const c_char;
|
|
|
+ let virt_addr = VirtAddr::new(path_ptr as usize);
|
|
|
// 权限校验
|
|
|
if path_ptr.is_null()
|
|
|
- || (from_user
|
|
|
- && unsafe { !verify_area(path_ptr as u64, PAGE_2M_SIZE as u64) })
|
|
|
+ || (from_user && verify_area(virt_addr, PAGE_2M_SIZE as usize).is_err())
|
|
|
{
|
|
|
return Err(SystemError::EINVAL);
|
|
|
}
|
|
@@ -526,9 +529,9 @@ 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 res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
|
|
|
+ let res = if from_user && verify_area(virt_addr, len as usize).is_err() {
|
|
|
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
|
|
Err(SystemError::EPERM)
|
|
|
} else if buf_vaddr == 0 {
|
|
@@ -547,12 +550,14 @@ impl Syscall {
|
|
|
let path_ptr = args[0];
|
|
|
let argv_ptr = args[1];
|
|
|
let env_ptr = args[2];
|
|
|
-
|
|
|
+ let virt_path_ptr = VirtAddr::new(path_ptr);
|
|
|
+ let virt_argv_ptr = VirtAddr::new(argv_ptr);
|
|
|
+ let virt_env_ptr = VirtAddr::new(env_ptr);
|
|
|
// 权限校验
|
|
|
if from_user
|
|
|
- && (unsafe { !verify_area(path_ptr as u64, PAGE_4K_SIZE as u64) }
|
|
|
- || unsafe { !verify_area(argv_ptr as u64, PAGE_4K_SIZE as u64) })
|
|
|
- || unsafe { !verify_area(env_ptr as u64, PAGE_4K_SIZE as u64) }
|
|
|
+ && (verify_area(virt_path_ptr, PAGE_4K_SIZE as usize).is_err()
|
|
|
+ || verify_area(virt_argv_ptr, PAGE_4K_SIZE as usize).is_err())
|
|
|
+ || verify_area(virt_env_ptr, PAGE_4K_SIZE as usize).is_err()
|
|
|
{
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -568,13 +573,13 @@ impl Syscall {
|
|
|
let wstatus = args[1] as *mut c_int;
|
|
|
let options = args[2] as c_int;
|
|
|
let rusage = args[3] as *mut c_void;
|
|
|
-
|
|
|
+ let virt_wstatus = VirtAddr::new(wstatus as usize);
|
|
|
+ let virt_rusage = VirtAddr::new(rusage as usize);
|
|
|
// 权限校验
|
|
|
// todo: 引入rusage之后,更正以下权限校验代码中,rusage的大小
|
|
|
if from_user
|
|
|
- && (unsafe {
|
|
|
- !verify_area(wstatus as u64, core::mem::size_of::<c_int>() as u64)
|
|
|
- } || unsafe { !verify_area(rusage as u64, PAGE_4K_SIZE as u64) })
|
|
|
+ && (verify_area(virt_wstatus, core::mem::size_of::<c_int>() as usize).is_err()
|
|
|
+ || verify_area(virt_rusage, PAGE_4K_SIZE as usize).is_err())
|
|
|
{
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -589,11 +594,10 @@ impl Syscall {
|
|
|
SYS_MKDIR => {
|
|
|
let path_ptr = args[0] as *const c_char;
|
|
|
let mode = args[1];
|
|
|
-
|
|
|
+ let virt_path_ptr = VirtAddr::new(path_ptr as usize);
|
|
|
let security_check = || {
|
|
|
if path_ptr.is_null()
|
|
|
- || (from_user
|
|
|
- && unsafe { !verify_area(path_ptr as u64, PAGE_2M_SIZE as u64) })
|
|
|
+ || (from_user && verify_area(virt_path_ptr, PAGE_2M_SIZE as usize).is_err())
|
|
|
{
|
|
|
return Err(SystemError::EINVAL);
|
|
|
}
|
|
@@ -617,12 +621,12 @@ impl Syscall {
|
|
|
SYS_NANOSLEEP => {
|
|
|
let req = args[0] as *const TimeSpec;
|
|
|
let rem = args[1] as *mut TimeSpec;
|
|
|
+ let virt_req = VirtAddr::new(req as usize);
|
|
|
+ let virt_rem = VirtAddr::new(rem as usize);
|
|
|
if from_user
|
|
|
- && (unsafe {
|
|
|
- !verify_area(req as u64, core::mem::size_of::<TimeSpec>() as u64)
|
|
|
- } || unsafe {
|
|
|
- !verify_area(rem as u64, core::mem::size_of::<TimeSpec>() as u64)
|
|
|
- })
|
|
|
+ && (verify_area(virt_req, core::mem::size_of::<TimeSpec>() as usize).is_err()
|
|
|
+ || verify_area(virt_rem, core::mem::size_of::<TimeSpec>() as usize)
|
|
|
+ .is_err())
|
|
|
{
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -633,10 +637,10 @@ impl Syscall {
|
|
|
SYS_CLOCK => Self::clock(),
|
|
|
SYS_PIPE => {
|
|
|
let pipefd = args[0] as *mut c_int;
|
|
|
+ let virt_pipefd = VirtAddr::new(pipefd as usize);
|
|
|
if from_user
|
|
|
- && unsafe {
|
|
|
- !verify_area(pipefd as u64, core::mem::size_of::<[c_int; 2]>() as u64)
|
|
|
- }
|
|
|
+ && verify_area(virt_pipefd, core::mem::size_of::<[c_int; 2]>() as usize)
|
|
|
+ .is_err()
|
|
|
{
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else if pipefd.is_null() {
|
|
@@ -651,7 +655,8 @@ impl Syscall {
|
|
|
let dirfd = args[0] as i32;
|
|
|
let pathname = args[1] as *const c_char;
|
|
|
let flags = args[2] as u32;
|
|
|
- if from_user && unsafe { !verify_area(pathname as u64, PAGE_4K_SIZE as u64) } {
|
|
|
+ let virt_pathname = VirtAddr::new(pathname as usize);
|
|
|
+ if from_user && verify_area(virt_pathname, PAGE_4K_SIZE as usize).is_err() {
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else if pathname.is_null() {
|
|
|
Err(SystemError::EFAULT)
|
|
@@ -710,8 +715,9 @@ impl Syscall {
|
|
|
SYS_SETSOCKOPT => {
|
|
|
let optval = args[3] as *const u8;
|
|
|
let optlen = args[4] as usize;
|
|
|
+ let virt_optval = VirtAddr::new(optval as usize);
|
|
|
// 验证optval的地址是否合法
|
|
|
- if unsafe { verify_area(optval as u64, optlen as u64) } == false {
|
|
|
+ if verify_area(virt_optval, optlen as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -722,18 +728,17 @@ impl Syscall {
|
|
|
SYS_GETSOCKOPT => {
|
|
|
let optval = args[3] as *mut u8;
|
|
|
let optlen = args[4] as *mut usize;
|
|
|
-
|
|
|
+ let virt_optval = VirtAddr::new(optval as usize);
|
|
|
+ let virt_optlen = VirtAddr::new(optlen as usize);
|
|
|
let security_check = || {
|
|
|
// 验证optval的地址是否合法
|
|
|
- if unsafe { verify_area(optval as u64, PAGE_4K_SIZE as u64) } == false {
|
|
|
+ if verify_area(virt_optval, PAGE_4K_SIZE as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
|
|
|
|
// 验证optlen的地址是否合法
|
|
|
- if unsafe { verify_area(optlen as u64, core::mem::size_of::<u32>() as u64) }
|
|
|
- == false
|
|
|
- {
|
|
|
+ if verify_area(virt_optlen, core::mem::size_of::<u32>() as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
@@ -750,8 +755,9 @@ impl Syscall {
|
|
|
SYS_CONNECT => {
|
|
|
let addr = args[1] as *const SockAddr;
|
|
|
let addrlen = args[2] as usize;
|
|
|
+ let virt_addr = VirtAddr::new(addr as usize);
|
|
|
// 验证addr的地址是否合法
|
|
|
- if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
|
|
|
+ if verify_area(virt_addr, addrlen as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -761,8 +767,9 @@ impl Syscall {
|
|
|
SYS_BIND => {
|
|
|
let addr = args[1] as *const SockAddr;
|
|
|
let addrlen = args[2] as usize;
|
|
|
+ let virt_addr = VirtAddr::new(addr as usize);
|
|
|
// 验证addr的地址是否合法
|
|
|
- if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
|
|
|
+ if verify_area(virt_addr, addrlen as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -776,11 +783,13 @@ impl Syscall {
|
|
|
let flags = args[3] as u32;
|
|
|
let addr = args[4] as *const SockAddr;
|
|
|
let addrlen = args[5] as usize;
|
|
|
+ let virt_buf = VirtAddr::new(buf as usize);
|
|
|
+ let virt_addr = VirtAddr::new(addr as usize);
|
|
|
// 验证buf的地址是否合法
|
|
|
- if unsafe { verify_area(buf as u64, len as u64) } == false {
|
|
|
+ if verify_area(virt_buf, len as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
Err(SystemError::EFAULT)
|
|
|
- } else if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
|
|
|
+ } else if verify_area(virt_addr, addrlen as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
@@ -795,25 +804,23 @@ impl Syscall {
|
|
|
let flags = args[3] as u32;
|
|
|
let addr = args[4] as *mut SockAddr;
|
|
|
let addrlen = args[5] as *mut usize;
|
|
|
-
|
|
|
+ let virt_buf = VirtAddr::new(buf as usize);
|
|
|
+ let virt_addrlen = VirtAddr::new(addrlen as usize);
|
|
|
+ let virt_addr = VirtAddr::new(addr as usize);
|
|
|
let security_check = || {
|
|
|
// 验证buf的地址是否合法
|
|
|
- if unsafe { verify_area(buf as u64, len as u64) } == false {
|
|
|
+ if verify_area(virt_buf, len as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
|
|
|
|
// 验证addrlen的地址是否合法
|
|
|
- if unsafe { verify_area(addrlen as u64, core::mem::size_of::<u32>() as u64) }
|
|
|
- == false
|
|
|
- {
|
|
|
+ if verify_area(virt_addrlen, core::mem::size_of::<u32>() as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
|
|
|
|
- if unsafe { verify_area(addr as u64, core::mem::size_of::<SockAddr>() as u64) }
|
|
|
- == false
|
|
|
- {
|
|
|
+ if verify_area(virt_addr, core::mem::size_of::<SockAddr>() as usize).is_err() {
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
@@ -831,14 +838,14 @@ impl Syscall {
|
|
|
SYS_RECVMSG => {
|
|
|
let msg = args[1] as *mut crate::net::syscall::MsgHdr;
|
|
|
let flags = args[2] as u32;
|
|
|
+ let virt_msg = VirtAddr::new(msg as usize);
|
|
|
let security_check = || {
|
|
|
// 验证msg的地址是否合法
|
|
|
- if unsafe {
|
|
|
- verify_area(
|
|
|
- msg as u64,
|
|
|
- core::mem::size_of::<crate::net::syscall::MsgHdr>() as u64,
|
|
|
- )
|
|
|
- } == false
|
|
|
+ if verify_area(
|
|
|
+ virt_msg,
|
|
|
+ core::mem::size_of::<crate::net::syscall::MsgHdr>() as usize,
|
|
|
+ )
|
|
|
+ .is_err()
|
|
|
{
|
|
|
// 地址空间超出了用户空间的范围,不合法
|
|
|
return Err(SystemError::EFAULT);
|
|
@@ -867,19 +874,19 @@ impl Syscall {
|
|
|
SYS_GETTIMEOFDAY => {
|
|
|
let timeval = args[0] as *mut PosixTimeval;
|
|
|
let timezone_ptr = args[1] as *mut PosixTimeZone;
|
|
|
+ let virt_timeval = VirtAddr::new(timeval as usize);
|
|
|
+ let virt_timezone_ptr = VirtAddr::new(timezone_ptr as usize);
|
|
|
let security_check = || {
|
|
|
- if unsafe {
|
|
|
- verify_area(timeval as u64, core::mem::size_of::<PosixTimeval>() as u64)
|
|
|
- } == false
|
|
|
+ if verify_area(virt_timeval, core::mem::size_of::<PosixTimeval>() as usize)
|
|
|
+ .is_err()
|
|
|
{
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
|
- if unsafe {
|
|
|
- verify_area(
|
|
|
- timezone_ptr as u64,
|
|
|
- core::mem::size_of::<PosixTimeZone>() as u64,
|
|
|
- )
|
|
|
- } == false
|
|
|
+ if verify_area(
|
|
|
+ virt_timezone_ptr,
|
|
|
+ core::mem::size_of::<PosixTimeZone>() as usize,
|
|
|
+ )
|
|
|
+ .is_err()
|
|
|
{
|
|
|
return Err(SystemError::EFAULT);
|
|
|
}
|
|
@@ -898,7 +905,8 @@ impl Syscall {
|
|
|
}
|
|
|
SYS_MMAP => {
|
|
|
let len = page_align_up(args[1]);
|
|
|
- if unsafe { !verify_area(args[0] as u64, len as u64) } {
|
|
|
+ let virt_addr = VirtAddr::new(args[0] as usize);
|
|
|
+ if verify_area(virt_addr, len as usize).is_err() {
|
|
|
Err(SystemError::EFAULT)
|
|
|
} else {
|
|
|
Self::mmap(
|
|
@@ -932,6 +940,18 @@ impl Syscall {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ SYS_FSTAT => {
|
|
|
+ let fd = args[0] as i32;
|
|
|
+ let kstat = args[1] as *mut PosixKstat;
|
|
|
+ let vaddr = VirtAddr::new(kstat as usize);
|
|
|
+ // FIXME 由于c中的verify_area与rust中的verify_area重名,所以在引入时加了前缀区分
|
|
|
+ // TODO 应该将用了c版本的verify_area都改为rust的verify_area
|
|
|
+ match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
|
|
|
+ Ok(_) => Self::fstat(fd, kstat),
|
|
|
+ Err(e) => Err(e),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
|
|
};
|
|
|
|