mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
refactor(process): 重构process下的系统调用 (#1184)
* refactor(process):迁移geteuid系统调用 * refactor(process):迁移getegid系统调用 * refactor(process):迁移getgid系统调用 * refactor(process):迁移getpgid系统调用 * refactor(process):迁移getpid系统调用 * refactor(process):迁移getppid系统调用 * refactor(process):迁移getsid系统调用 * refactor(process):迁移gettid系统调用 * refactor(process):迁移getuid系统调用 * refactor(process):迁移set_tid_address系统调用 * refactor(process):迁移setfsgid系统调用 * refactor(process):迁移setfsuid系统调用 * refactor(process):迁移setgid系统调用 * refactor(process):迁移setpgid系统调用 * refactor(process):迁移setresgid系统调用 * refactor(process):迁移setresuid系统调用 * refactor(process):迁移setsid系统调用 * refactor(process):迁移setuid系统调用 * refactor(process):删除部分已迁移的syscall(id相关)的原有部分 * refactor(process):make fmt * refactor(process):迁移sys_get_rusage系统调用 * refactor(process):迁移exit exit_group 系统调用 * refactor(process):删除重构syscall下的mod中的全架构条件编译 * refactor(process):迁移sys_wait4系统调用 * refactor(process):迁移sys_getrlimit sys_prlimit64 系统调用 * make fmt * refactor(process):迁移sys_uname系统调用 * fix(ipc):修复rebase时的错误冲突 * refactor(process):修改已迁移的系统调用的handle参数from_user-->frame * refactor(process):迁移execve系统调用 * refactor(process):迁移clone系统调用 * refactor(process):迁移fork、vfork系统调用 * refactor(process):删除原有syscall文件,将迁移后的文件夹重命名为syscall * refactor(process):修复条件编译错误
This commit is contained in:
parent
58e7943c13
commit
326cf3e0a3
@ -13,11 +13,10 @@ use crate::{
|
||||
namespaces::NsProxy,
|
||||
net::net_core::net_init,
|
||||
process::{
|
||||
exec::ProcInitInfo, kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags,
|
||||
ProcessManager,
|
||||
exec::ProcInitInfo, execve::do_execve, kthread::KernelThreadMechanism, stdio::stdio_init,
|
||||
ProcessFlags, ProcessManager,
|
||||
},
|
||||
smp::smp_init,
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
|
||||
@ -164,7 +163,7 @@ fn run_init_process(
|
||||
ProcessManager::current_pcb().set_nsproxy(NsProxy::new()); // 初始化init进程的namespace
|
||||
let path = proc_init_info.proc_name.to_str().unwrap();
|
||||
|
||||
Syscall::do_execve(
|
||||
do_execve(
|
||||
path.to_string(),
|
||||
proc_init_info.args.clone(),
|
||||
proc_init_info.envs.clone(),
|
||||
|
@ -25,8 +25,8 @@ use crate::libs::rbtree::RBTree;
|
||||
use crate::libs::rwlock::RwLock;
|
||||
use crate::libs::wait_queue::WaitQueue;
|
||||
use crate::process::fork::CloneFlags;
|
||||
use crate::process::geteuid::do_geteuid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::Syscall;
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct MntNamespace {
|
||||
@ -230,7 +230,7 @@ impl MntNamespace {
|
||||
) -> Result<Option<Arc<UCounts>>, SystemError> {
|
||||
Ok(self
|
||||
.ucounts
|
||||
.inc_ucounts(user_ns, Syscall::geteuid()?, MntNamespaces))
|
||||
.inc_ucounts(user_ns, do_geteuid()?, MntNamespaces))
|
||||
}
|
||||
|
||||
pub fn dec_mnt_namespace(&self, uc: Arc<UCounts>) {
|
||||
|
@ -9,8 +9,8 @@ use crate::container_of;
|
||||
use crate::filesystem::vfs::{IndexNode, ROOT_INODE};
|
||||
use crate::namespaces::namespace::NsOperations;
|
||||
use crate::process::fork::CloneFlags;
|
||||
use crate::process::geteuid::do_geteuid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::Syscall;
|
||||
use crate::{libs::rwlock::RwLock, process::Pid};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
@ -264,7 +264,7 @@ impl PidNamespace {
|
||||
) -> Result<Option<Arc<UCounts>>, SystemError> {
|
||||
Ok(self
|
||||
.ucounts
|
||||
.inc_ucounts(user_ns, Syscall::geteuid()?, PidNamespaces))
|
||||
.inc_ucounts(user_ns, do_geteuid()?, PidNamespaces))
|
||||
}
|
||||
|
||||
pub fn dec_pid_namespaces(&mut self, uc: Arc<UCounts>) {
|
||||
|
113
kernel/src/process/execve.rs
Normal file
113
kernel/src/process/execve.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use crate::arch::CurrentIrqArch;
|
||||
use crate::exception::InterruptArch;
|
||||
use crate::process::exec::{load_binary_file, ExecParam, ExecParamFlags};
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::Syscall;
|
||||
use crate::{libs::rand::rand_bytes, mm::ucontext::AddressSpace};
|
||||
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use alloc::{ffi::CString, string::String, sync::Arc, vec::Vec};
|
||||
use system_error::SystemError;
|
||||
pub fn do_execve(
|
||||
path: String,
|
||||
argv: Vec<CString>,
|
||||
envp: Vec<CString>,
|
||||
regs: &mut TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
let address_space = AddressSpace::new(true).expect("Failed to create new address space");
|
||||
// debug!("to load binary file");
|
||||
let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
|
||||
let old_vm = do_execve_switch_user_vm(address_space.clone());
|
||||
|
||||
// 加载可执行文件
|
||||
let load_result = load_binary_file(&mut param).inspect_err(|_| {
|
||||
if let Some(old_vm) = old_vm {
|
||||
do_execve_switch_user_vm(old_vm);
|
||||
}
|
||||
})?;
|
||||
|
||||
// debug!("load binary file done");
|
||||
// debug!("argv: {:?}, envp: {:?}", argv, envp);
|
||||
param.init_info_mut().args = argv;
|
||||
param.init_info_mut().envs = envp;
|
||||
// // 生成16字节随机数
|
||||
param.init_info_mut().rand_num = rand_bytes::<16>();
|
||||
|
||||
// 把proc_init_info写到用户栈上
|
||||
let mut ustack_message = unsafe {
|
||||
address_space
|
||||
.write()
|
||||
.user_stack_mut()
|
||||
.expect("No user stack found")
|
||||
.clone_info_only()
|
||||
};
|
||||
let (user_sp, argv_ptr) = unsafe {
|
||||
param
|
||||
.init_info_mut()
|
||||
.push_at(
|
||||
// address_space
|
||||
// .write()
|
||||
// .user_stack_mut()
|
||||
// .expect("No user stack found"),
|
||||
&mut ustack_message,
|
||||
)
|
||||
.expect("Failed to push proc_init_info to user stack")
|
||||
};
|
||||
address_space.write().user_stack = Some(ustack_message);
|
||||
|
||||
Syscall::arch_do_execve(regs, ¶m, &load_result, user_sp, argv_ptr)
|
||||
}
|
||||
|
||||
/// 切换用户虚拟内存空间
|
||||
///
|
||||
/// 该函数用于在执行系统调用 `execve` 时切换用户进程的虚拟内存空间。
|
||||
///
|
||||
/// # 参数
|
||||
/// - `new_vm`: 新的用户地址空间,类型为 `Arc<AddressSpace>`。
|
||||
///
|
||||
/// # 返回值
|
||||
/// - 返回旧的用户地址空间的引用,类型为 `Option<Arc<AddressSpace>>`。
|
||||
///
|
||||
/// # 错误处理
|
||||
/// 如果地址空间切换失败,函数会触发断言失败,并输出错误信息。
|
||||
fn do_execve_switch_user_vm(new_vm: Arc<AddressSpace>) -> Option<Arc<AddressSpace>> {
|
||||
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
// log::debug!(
|
||||
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
|
||||
// pcb.pid(),
|
||||
// path,
|
||||
// argv,
|
||||
// envp
|
||||
// );
|
||||
|
||||
let mut basic_info = pcb.basic_mut();
|
||||
// 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
|
||||
let old_address_space = basic_info.user_vm();
|
||||
|
||||
// 在pcb中原来的用户地址空间
|
||||
unsafe {
|
||||
basic_info.set_user_vm(None);
|
||||
}
|
||||
// 创建新的地址空间并设置为当前地址空间
|
||||
unsafe {
|
||||
basic_info.set_user_vm(Some(new_vm.clone()));
|
||||
}
|
||||
|
||||
// to avoid deadlock
|
||||
drop(basic_info);
|
||||
|
||||
assert!(
|
||||
AddressSpace::is_current(&new_vm),
|
||||
"Failed to set address space"
|
||||
);
|
||||
// debug!("Switch to new address space");
|
||||
|
||||
// 切换到新的用户地址空间
|
||||
unsafe { new_vm.read().user_mapper.utable.make_current() };
|
||||
|
||||
drop(irq_guard);
|
||||
|
||||
old_address_space
|
||||
}
|
8
kernel/src/process/geteuid.rs
Normal file
8
kernel/src/process/geteuid.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::process::ProcessManager;
|
||||
|
||||
pub fn do_geteuid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().euid.data());
|
||||
}
|
@ -76,8 +76,10 @@ use self::{cred::Cred, kthread::WorkerPrivate};
|
||||
pub mod abi;
|
||||
pub mod cred;
|
||||
pub mod exec;
|
||||
pub mod execve;
|
||||
pub mod exit;
|
||||
pub mod fork;
|
||||
pub mod geteuid;
|
||||
pub mod idle;
|
||||
pub mod kthread;
|
||||
pub mod pid;
|
||||
|
@ -1,683 +0,0 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use alloc::{
|
||||
ffi::CString,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use log::error;
|
||||
use system_error::SystemError;
|
||||
|
||||
use super::{
|
||||
abi::WaitOption,
|
||||
cred::{Kgid, Kuid},
|
||||
exec::{load_binary_file, ExecParam, ExecParamFlags},
|
||||
exit::kernel_wait4,
|
||||
fork::{CloneFlags, KernelCloneArgs},
|
||||
resource::{RLimit64, RLimitID, RUsage, RUsageWho},
|
||||
KernelStack, Pgid, Pid, ProcessManager,
|
||||
};
|
||||
use crate::{
|
||||
arch::{interrupt::TrapFrame, CurrentIrqArch, MMArch},
|
||||
exception::InterruptArch,
|
||||
filesystem::{
|
||||
procfs::procfs_register_pid,
|
||||
vfs::{file::FileDescriptorVec, MAX_PATHLEN},
|
||||
},
|
||||
libs::rand::rand_bytes,
|
||||
mm::{
|
||||
ucontext::{AddressSpace, UserStack},
|
||||
verify_area, MemoryManagementArch, VirtAddr,
|
||||
},
|
||||
process::ProcessControlBlock,
|
||||
sched::completion::Completion,
|
||||
syscall::{
|
||||
user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
};
|
||||
|
||||
//参考资料:https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PosixOldUtsName {
|
||||
pub sysname: [u8; 65],
|
||||
pub nodename: [u8; 65],
|
||||
pub release: [u8; 65],
|
||||
pub version: [u8; 65],
|
||||
pub machine: [u8; 65],
|
||||
}
|
||||
|
||||
impl PosixOldUtsName {
|
||||
pub fn new() -> Self {
|
||||
const SYS_NAME: &[u8] = b"Linux";
|
||||
const NODENAME: &[u8] = b"DragonOS";
|
||||
const RELEASE: &[u8] = b"5.19.0";
|
||||
const VERSION: &[u8] = b"5.19.0";
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const MACHINE: &[u8] = b"x86_64";
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const MACHINE: &[u8] = b"aarch64";
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
const MACHINE: &[u8] = b"riscv64";
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
const MACHINE: &[u8] = b"longarch64";
|
||||
|
||||
let mut r = Self {
|
||||
sysname: [0; 65],
|
||||
nodename: [0; 65],
|
||||
release: [0; 65],
|
||||
version: [0; 65],
|
||||
machine: [0; 65],
|
||||
};
|
||||
|
||||
r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME);
|
||||
r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME);
|
||||
r.release[0..RELEASE.len()].copy_from_slice(RELEASE);
|
||||
r.version[0..VERSION.len()].copy_from_slice(VERSION);
|
||||
r.machine[0..MACHINE.len()].copy_from_slice(MACHINE);
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall {
|
||||
pub fn fork(frame: &TrapFrame) -> Result<usize, SystemError> {
|
||||
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
|
||||
}
|
||||
|
||||
pub fn vfork(frame: &TrapFrame) -> Result<usize, SystemError> {
|
||||
// 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit),
|
||||
// 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的)
|
||||
Self::fork(frame)
|
||||
|
||||
// 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏
|
||||
// ProcessManager::fork(
|
||||
// frame,
|
||||
// CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
|
||||
// )
|
||||
// .map(|pid| pid.into())
|
||||
}
|
||||
|
||||
pub fn execve(
|
||||
path: *const u8,
|
||||
argv: *const *const u8,
|
||||
envp: *const *const u8,
|
||||
frame: &mut TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
// debug!(
|
||||
// "execve path: {:?}, argv: {:?}, envp: {:?}\n",
|
||||
// path,
|
||||
// argv,
|
||||
// envp
|
||||
// );
|
||||
// debug!(
|
||||
// "before execve: strong count: {}",
|
||||
// Arc::strong_count(&ProcessManager::current_pcb())
|
||||
// );
|
||||
|
||||
if path.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let x = || {
|
||||
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
|
||||
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
|
||||
Ok((path, argv, envp))
|
||||
};
|
||||
let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
|
||||
error!("Failed to execve: {:?}", e);
|
||||
})?;
|
||||
|
||||
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
|
||||
ProcessManager::current_pcb()
|
||||
.basic_mut()
|
||||
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
||||
|
||||
Self::do_execve(path.clone(), argv, envp, frame)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
// 关闭设置了O_CLOEXEC的文件描述符
|
||||
let fd_table = pcb.fd_table();
|
||||
fd_table.write().close_on_exec();
|
||||
// debug!(
|
||||
// "after execve: strong count: {}",
|
||||
// Arc::strong_count(&ProcessManager::current_pcb())
|
||||
// );
|
||||
pcb.set_execute_path(path);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn do_execve(
|
||||
path: String,
|
||||
argv: Vec<CString>,
|
||||
envp: Vec<CString>,
|
||||
regs: &mut TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
let address_space = AddressSpace::new(true).expect("Failed to create new address space");
|
||||
// debug!("to load binary file");
|
||||
let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
|
||||
let old_vm = do_execve_switch_user_vm(address_space.clone());
|
||||
|
||||
// 加载可执行文件
|
||||
let load_result = load_binary_file(&mut param).inspect_err(|_| {
|
||||
if let Some(old_vm) = old_vm {
|
||||
do_execve_switch_user_vm(old_vm);
|
||||
}
|
||||
})?;
|
||||
|
||||
// debug!("load binary file done");
|
||||
// debug!("argv: {:?}, envp: {:?}", argv, envp);
|
||||
param.init_info_mut().args = argv;
|
||||
param.init_info_mut().envs = envp;
|
||||
// // 生成16字节随机数
|
||||
param.init_info_mut().rand_num = rand_bytes::<16>();
|
||||
|
||||
// 把proc_init_info写到用户栈上
|
||||
let mut ustack_message = unsafe {
|
||||
address_space
|
||||
.write()
|
||||
.user_stack_mut()
|
||||
.expect("No user stack found")
|
||||
.clone_info_only()
|
||||
};
|
||||
let (user_sp, argv_ptr) = unsafe {
|
||||
param
|
||||
.init_info_mut()
|
||||
.push_at(
|
||||
// address_space
|
||||
// .write()
|
||||
// .user_stack_mut()
|
||||
// .expect("No user stack found"),
|
||||
&mut ustack_message,
|
||||
)
|
||||
.expect("Failed to push proc_init_info to user stack")
|
||||
};
|
||||
address_space.write().user_stack = Some(ustack_message);
|
||||
|
||||
Self::arch_do_execve(regs, ¶m, &load_result, user_sp, argv_ptr)
|
||||
}
|
||||
|
||||
pub fn wait4(
|
||||
pid: i32,
|
||||
wstatus: *mut i32,
|
||||
options: i32,
|
||||
rusage: *mut c_void,
|
||||
) -> Result<usize, SystemError> {
|
||||
let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let wstatus_buf = if wstatus.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(UserBufferWriter::new(
|
||||
wstatus,
|
||||
core::mem::size_of::<i32>(),
|
||||
true,
|
||||
)?)
|
||||
};
|
||||
|
||||
let mut tmp_rusage = if rusage.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(RUsage::default())
|
||||
};
|
||||
|
||||
let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?;
|
||||
|
||||
if !rusage.is_null() {
|
||||
let mut rusage_buf = UserBufferWriter::new::<RUsage>(
|
||||
rusage as *mut RUsage,
|
||||
core::mem::size_of::<RUsage>(),
|
||||
true,
|
||||
)?;
|
||||
rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?;
|
||||
}
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
/// # 退出进程
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - status: 退出状态
|
||||
pub fn exit(status: usize) -> ! {
|
||||
ProcessManager::exit((status & 0xff) << 8);
|
||||
}
|
||||
|
||||
/// @brief 获取当前进程的pid
|
||||
pub fn getpid() -> Result<Pid, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
// if let Some(pid_ns) = ¤t_pcb.get_nsproxy().read().pid_namespace {
|
||||
// // 获取该进程在命名空间中的 PID
|
||||
// return Ok(current_pcb.pid_strcut().read().numbers[pid_ns.level].nr);
|
||||
// // 返回命名空间中的 PID
|
||||
// }
|
||||
// 默认返回 tgid
|
||||
Ok(current_pcb.tgid())
|
||||
}
|
||||
|
||||
/// @brief 获取指定进程的pgid
|
||||
///
|
||||
/// @param pid 指定一个进程号
|
||||
///
|
||||
/// @return 成功,指定进程的进程组id
|
||||
/// @return 错误,不存在该进程
|
||||
pub fn getpgid(pid: Pid) -> Result<Pgid, SystemError> {
|
||||
if pid == Pid(0) {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
return Ok(current_pcb.pgid());
|
||||
}
|
||||
let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
return Ok(target_proc.pgid());
|
||||
}
|
||||
|
||||
/// 设置指定进程的pgid
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - pid: 指定进程号
|
||||
/// - pgid: 新的进程组号
|
||||
///
|
||||
/// ## 返回值
|
||||
/// 无
|
||||
pub fn setpgid(pid: Pid, pgid: Pgid) -> Result<usize, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let pid = if pid == Pid(0) {
|
||||
current_pcb.pid()
|
||||
} else {
|
||||
pid
|
||||
};
|
||||
let pgid = if pgid == Pgid::from(0) {
|
||||
Pgid::from(pid.into())
|
||||
} else {
|
||||
pgid
|
||||
};
|
||||
if pid != current_pcb.pid() && !current_pcb.contain_child(&pid) {
|
||||
return Err(SystemError::ESRCH);
|
||||
}
|
||||
|
||||
if pgid.into() != pid.into() && ProcessManager::find_process_group(pgid).is_none() {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
pcb.join_other_group(pgid)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// 创建新的会话
|
||||
pub fn setsid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let session = pcb.go_to_new_session()?;
|
||||
let mut guard = pcb.sig_info_mut();
|
||||
guard.set_tty(None);
|
||||
Ok(session.sid().into())
|
||||
}
|
||||
|
||||
/// 获取指定进程的会话id
|
||||
///
|
||||
/// 若pid为0,则返回当前进程的会话id
|
||||
///
|
||||
/// 若pid不为0,则返回指定进程的会话id
|
||||
pub fn getsid(pid: Pid) -> Result<usize, SystemError> {
|
||||
let session = ProcessManager::current_pcb().session().unwrap();
|
||||
let sid = session.sid().into();
|
||||
if pid == Pid(0) {
|
||||
return Ok(sid);
|
||||
}
|
||||
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
if !Arc::ptr_eq(&session, &pcb.session().unwrap()) {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
return Ok(sid);
|
||||
}
|
||||
|
||||
/// @brief 获取当前进程的父进程id
|
||||
///
|
||||
/// 若为initproc则ppid设置为0
|
||||
pub fn getppid() -> Result<Pid, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
return Ok(current_pcb.basic().ppid());
|
||||
}
|
||||
|
||||
pub fn clone(
|
||||
current_trapframe: &TrapFrame,
|
||||
clone_args: KernelCloneArgs,
|
||||
) -> Result<usize, SystemError> {
|
||||
let flags = clone_args.flags;
|
||||
|
||||
let vfork = Arc::new(Completion::new());
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_PIDFD)
|
||||
&& flags.contains(CloneFlags::CLONE_PARENT_SETTID)
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let new_kstack = KernelStack::new()?;
|
||||
let name = current_pcb.basic().name().to_string();
|
||||
|
||||
let pcb = ProcessControlBlock::new(name, new_kstack);
|
||||
// 克隆pcb
|
||||
ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?;
|
||||
|
||||
// 向procfs注册进程
|
||||
procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
|
||||
pcb.pid(),
|
||||
e
|
||||
)
|
||||
});
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_VFORK) {
|
||||
pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
|
||||
}
|
||||
|
||||
if pcb.thread.read_irqsave().set_child_tid.is_some() {
|
||||
let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
|
||||
let mut writer =
|
||||
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
|
||||
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
|
||||
}
|
||||
|
||||
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
|
||||
pcb.pid(),
|
||||
e
|
||||
)
|
||||
});
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_VFORK) {
|
||||
// 等待子进程结束或者exec;
|
||||
vfork.wait_for_completion_interruptible()?;
|
||||
}
|
||||
|
||||
return Ok(pcb.pid().0);
|
||||
}
|
||||
|
||||
/// 设置线程地址
|
||||
pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> {
|
||||
verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>())
|
||||
.map_err(|_| SystemError::EFAULT)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
|
||||
Ok(pcb.pid.0)
|
||||
}
|
||||
|
||||
pub fn gettid() -> Result<Pid, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
Ok(pcb.pid)
|
||||
}
|
||||
|
||||
pub fn getuid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().uid.data());
|
||||
}
|
||||
|
||||
pub fn getgid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().gid.data());
|
||||
}
|
||||
|
||||
pub fn geteuid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().euid.data());
|
||||
}
|
||||
|
||||
pub fn getegid() -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().egid.data());
|
||||
}
|
||||
|
||||
pub fn setuid(uid: usize) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if guard.uid.data() == 0 {
|
||||
guard.setuid(uid);
|
||||
guard.seteuid(uid);
|
||||
guard.setsuid(uid);
|
||||
} else if uid == guard.uid.data() || uid == guard.suid.data() {
|
||||
guard.seteuid(uid);
|
||||
} else {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn setgid(gid: usize) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if guard.egid.data() == 0 {
|
||||
guard.setgid(gid);
|
||||
guard.setegid(gid);
|
||||
guard.setsgid(gid);
|
||||
guard.setfsgid(gid);
|
||||
} else if guard.gid.data() == gid || guard.sgid.data() == gid {
|
||||
guard.setegid(gid);
|
||||
guard.setfsgid(gid);
|
||||
} else {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn seteuid(euid: usize) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if euid != usize::MAX {
|
||||
guard.seteuid(euid);
|
||||
}
|
||||
|
||||
let euid = guard.euid.data();
|
||||
guard.setfsuid(euid);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn setegid(egid: usize) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if egid != usize::MAX {
|
||||
guard.setegid(egid);
|
||||
}
|
||||
|
||||
let egid = guard.egid.data();
|
||||
guard.setfsgid(egid);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn setfsuid(fsuid: usize) -> Result<usize, SystemError> {
|
||||
let fsuid = Kuid::new(fsuid);
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
let old_fsuid = guard.fsuid;
|
||||
|
||||
if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid {
|
||||
guard.setfsuid(fsuid.data());
|
||||
}
|
||||
|
||||
Ok(old_fsuid.data())
|
||||
}
|
||||
|
||||
pub fn setfsgid(fsgid: usize) -> Result<usize, SystemError> {
|
||||
let fsgid = Kgid::new(fsgid);
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
let old_fsgid = guard.fsgid;
|
||||
|
||||
if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid {
|
||||
guard.setfsgid(fsgid.data());
|
||||
}
|
||||
|
||||
Ok(old_fsgid.data())
|
||||
}
|
||||
|
||||
pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> {
|
||||
let who = RUsageWho::try_from(who)?;
|
||||
let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let ubuf = writer.buffer::<RUsage>(0).unwrap();
|
||||
ubuf.copy_from_slice(&[rusage]);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// # 设置资源限制
|
||||
///
|
||||
/// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - pid: 进程号
|
||||
/// - resource: 资源类型
|
||||
/// - new_limit: 新的资源限制
|
||||
/// - old_limit: 旧的资源限制
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// - 成功,0
|
||||
/// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit
|
||||
///
|
||||
pub fn prlimit64(
|
||||
_pid: Pid,
|
||||
resource: usize,
|
||||
_new_limit: *const RLimit64,
|
||||
old_limit: *mut RLimit64,
|
||||
) -> Result<usize, SystemError> {
|
||||
let resource = RLimitID::try_from(resource)?;
|
||||
let mut writer = None;
|
||||
|
||||
if !old_limit.is_null() {
|
||||
writer = Some(UserBufferWriter::new(
|
||||
old_limit,
|
||||
core::mem::size_of::<RLimit64>(),
|
||||
true,
|
||||
)?);
|
||||
}
|
||||
|
||||
match resource {
|
||||
RLimitID::Stack => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
|
||||
rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
RLimitID::Nofile => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
|
||||
rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
RLimitID::As | RLimitID::Rss => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
|
||||
rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> {
|
||||
let mut writer =
|
||||
UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?;
|
||||
writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// 切换用户虚拟内存空间
|
||||
///
|
||||
/// 该函数用于在执行系统调用 `execve` 时切换用户进程的虚拟内存空间。
|
||||
///
|
||||
/// # 参数
|
||||
/// - `new_vm`: 新的用户地址空间,类型为 `Arc<AddressSpace>`。
|
||||
///
|
||||
/// # 返回值
|
||||
/// - 返回旧的用户地址空间的引用,类型为 `Option<Arc<AddressSpace>>`。
|
||||
///
|
||||
/// # 错误处理
|
||||
/// 如果地址空间切换失败,函数会触发断言失败,并输出错误信息。
|
||||
fn do_execve_switch_user_vm(new_vm: Arc<AddressSpace>) -> Option<Arc<AddressSpace>> {
|
||||
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
// log::debug!(
|
||||
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
|
||||
// pcb.pid(),
|
||||
// path,
|
||||
// argv,
|
||||
// envp
|
||||
// );
|
||||
|
||||
let mut basic_info = pcb.basic_mut();
|
||||
// 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
|
||||
let old_address_space = basic_info.user_vm();
|
||||
|
||||
// 在pcb中原来的用户地址空间
|
||||
unsafe {
|
||||
basic_info.set_user_vm(None);
|
||||
}
|
||||
// 创建新的地址空间并设置为当前地址空间
|
||||
unsafe {
|
||||
basic_info.set_user_vm(Some(new_vm.clone()));
|
||||
}
|
||||
|
||||
// to avoid deadlock
|
||||
drop(basic_info);
|
||||
|
||||
assert!(
|
||||
AddressSpace::is_current(&new_vm),
|
||||
"Failed to set address space"
|
||||
);
|
||||
// debug!("Switch to new address space");
|
||||
|
||||
// 切换到新的用户地址空间
|
||||
unsafe { new_vm.read().user_mapper.utable.make_current() };
|
||||
|
||||
drop(irq_guard);
|
||||
|
||||
old_address_space
|
||||
}
|
81
kernel/src/process/syscall/mod.rs
Normal file
81
kernel/src/process/syscall/mod.rs
Normal file
@ -0,0 +1,81 @@
|
||||
mod sys_clone;
|
||||
mod sys_execve;
|
||||
mod sys_exit;
|
||||
mod sys_exit_group;
|
||||
mod sys_get_rusage;
|
||||
mod sys_getegid;
|
||||
mod sys_geteuid;
|
||||
mod sys_getgid;
|
||||
mod sys_getpgid;
|
||||
mod sys_getpid;
|
||||
mod sys_getppid;
|
||||
mod sys_getsid;
|
||||
mod sys_gettid;
|
||||
mod sys_getuid;
|
||||
mod sys_prlimit64;
|
||||
mod sys_set_tid_address;
|
||||
mod sys_setfsgid;
|
||||
mod sys_setfsuid;
|
||||
mod sys_setgid;
|
||||
mod sys_setpgid;
|
||||
mod sys_setresgid;
|
||||
mod sys_setresuid;
|
||||
mod sys_setsid;
|
||||
mod sys_setuid;
|
||||
mod sys_uname;
|
||||
mod sys_wait4;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod sys_fork;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod sys_getrlimit;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod sys_vfork;
|
||||
|
||||
//参考资料:https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PosixOldUtsName {
|
||||
pub sysname: [u8; 65],
|
||||
pub nodename: [u8; 65],
|
||||
pub release: [u8; 65],
|
||||
pub version: [u8; 65],
|
||||
pub machine: [u8; 65],
|
||||
}
|
||||
|
||||
impl PosixOldUtsName {
|
||||
pub fn new() -> Self {
|
||||
const SYS_NAME: &[u8] = b"Linux";
|
||||
const NODENAME: &[u8] = b"DragonOS";
|
||||
const RELEASE: &[u8] = b"5.19.0";
|
||||
const VERSION: &[u8] = b"5.19.0";
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const MACHINE: &[u8] = b"x86_64";
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const MACHINE: &[u8] = b"aarch64";
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
const MACHINE: &[u8] = b"riscv64";
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
const MACHINE: &[u8] = b"longarch64";
|
||||
|
||||
let mut r = Self {
|
||||
sysname: [0; 65],
|
||||
nodename: [0; 65],
|
||||
release: [0; 65],
|
||||
version: [0; 65],
|
||||
machine: [0; 65],
|
||||
};
|
||||
|
||||
r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME);
|
||||
r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME);
|
||||
r.release[0..RELEASE.len()].copy_from_slice(RELEASE);
|
||||
r.version[0..VERSION.len()].copy_from_slice(VERSION);
|
||||
r.machine[0..MACHINE.len()].copy_from_slice(MACHINE);
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
128
kernel/src/process/syscall/sys_clone.rs
Normal file
128
kernel/src/process/syscall/sys_clone.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_CLONE;
|
||||
use crate::filesystem::procfs::procfs_register_pid;
|
||||
use crate::mm::{verify_area, VirtAddr};
|
||||
use crate::process::fork::{CloneFlags, KernelCloneArgs};
|
||||
use crate::process::{KernelStack, ProcessControlBlock, ProcessManager};
|
||||
use crate::sched::completion::Completion;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use crate::syscall::user_access::UserBufferWriter;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{string::ToString, sync::Arc};
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysClone;
|
||||
|
||||
impl SysClone {
|
||||
fn parent_tid(args: &[usize]) -> VirtAddr {
|
||||
VirtAddr::new(args[2])
|
||||
}
|
||||
|
||||
fn child_tid(args: &[usize]) -> VirtAddr {
|
||||
VirtAddr::new(args[3])
|
||||
}
|
||||
|
||||
fn flags(args: &[usize]) -> CloneFlags {
|
||||
CloneFlags::from_bits_truncate(args[0] as u64)
|
||||
}
|
||||
|
||||
fn stack(args: &[usize]) -> usize {
|
||||
args[1]
|
||||
}
|
||||
|
||||
fn tls(args: &[usize]) -> usize {
|
||||
args[4]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysClone {
|
||||
fn num_args(&self) -> usize {
|
||||
5
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let parent_tid = Self::parent_tid(args);
|
||||
let child_tid = Self::child_tid(args);
|
||||
|
||||
// 地址校验
|
||||
verify_area(parent_tid, core::mem::size_of::<i32>())?;
|
||||
verify_area(child_tid, core::mem::size_of::<i32>())?;
|
||||
|
||||
let flags = Self::flags(args);
|
||||
let stack = Self::stack(args);
|
||||
let tls = Self::tls(args);
|
||||
|
||||
let mut clone_args = KernelCloneArgs::new();
|
||||
clone_args.flags = flags;
|
||||
clone_args.stack = stack;
|
||||
clone_args.parent_tid = parent_tid;
|
||||
clone_args.child_tid = child_tid;
|
||||
clone_args.tls = tls;
|
||||
|
||||
let vfork = Arc::new(Completion::new());
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_PIDFD)
|
||||
&& flags.contains(CloneFlags::CLONE_PARENT_SETTID)
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let new_kstack = KernelStack::new()?;
|
||||
let name = current_pcb.basic().name().to_string();
|
||||
|
||||
let pcb = ProcessControlBlock::new(name, new_kstack);
|
||||
// 克隆pcb
|
||||
ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, frame)?;
|
||||
|
||||
// 向procfs注册进程
|
||||
procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
|
||||
pcb.pid(),
|
||||
e
|
||||
)
|
||||
});
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_VFORK) {
|
||||
pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
|
||||
}
|
||||
|
||||
if pcb.thread.read_irqsave().set_child_tid.is_some() {
|
||||
let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
|
||||
let mut writer =
|
||||
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
|
||||
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
|
||||
}
|
||||
|
||||
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
|
||||
pcb.pid(),
|
||||
e
|
||||
)
|
||||
});
|
||||
|
||||
if flags.contains(CloneFlags::CLONE_VFORK) {
|
||||
// 等待子进程结束或者exec;
|
||||
vfork.wait_for_completion_interruptible()?;
|
||||
}
|
||||
|
||||
return Ok(pcb.pid().0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new(
|
||||
"parent_tid",
|
||||
format!("{:#x}", Self::parent_tid(args).data()),
|
||||
),
|
||||
FormattedSyscallParam::new("child_tid", format!("{:#x}", Self::child_tid(args).data())),
|
||||
FormattedSyscallParam::new("flags", format!("{:#x}", Self::flags(args))),
|
||||
FormattedSyscallParam::new("stack", format!("{:#x}", Self::stack(args))),
|
||||
FormattedSyscallParam::new("tls", format!("{:#x}", Self::tls(args))),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_CLONE, SysClone);
|
98
kernel/src/process/syscall/sys_execve.rs
Normal file
98
kernel/src/process/syscall/sys_execve.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use log::error;
|
||||
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_EXECVE;
|
||||
use crate::filesystem::vfs::MAX_PATHLEN;
|
||||
use crate::mm::page::PAGE_4K_SIZE;
|
||||
use crate::mm::{verify_area, VirtAddr};
|
||||
use crate::process::execve::do_execve;
|
||||
use crate::process::{ProcessControlBlock, ProcessManager};
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use crate::syscall::user_access::{check_and_clone_cstr, check_and_clone_cstr_array};
|
||||
use alloc::{ffi::CString, vec::Vec};
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysExecve;
|
||||
|
||||
impl SysExecve {
|
||||
fn path_ptr(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
|
||||
fn argv_ptr(args: &[usize]) -> usize {
|
||||
args[1]
|
||||
}
|
||||
|
||||
fn env_ptr(args: &[usize]) -> usize {
|
||||
args[2]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysExecve {
|
||||
fn num_args(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let path_ptr = Self::path_ptr(args);
|
||||
let argv_ptr = Self::argv_ptr(args);
|
||||
let env_ptr = Self::env_ptr(args);
|
||||
|
||||
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 frame.is_from_user()
|
||||
&& (verify_area(virt_path_ptr, MAX_PATHLEN).is_err()
|
||||
|| verify_area(virt_argv_ptr, PAGE_4K_SIZE).is_err())
|
||||
|| verify_area(virt_env_ptr, PAGE_4K_SIZE).is_err()
|
||||
{
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
let path = path_ptr as *const u8;
|
||||
let argv = argv_ptr as *const *const u8;
|
||||
let envp = env_ptr as *const *const u8;
|
||||
|
||||
if path.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let x = || {
|
||||
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
|
||||
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
|
||||
Ok((path, argv, envp))
|
||||
};
|
||||
let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
|
||||
error!("Failed to execve: {:?}", e);
|
||||
})?;
|
||||
|
||||
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
|
||||
ProcessManager::current_pcb()
|
||||
.basic_mut()
|
||||
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
||||
|
||||
do_execve(path.clone(), argv, envp, frame)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
// 关闭设置了O_CLOEXEC的文件描述符
|
||||
let fd_table = pcb.fd_table();
|
||||
fd_table.write().close_on_exec();
|
||||
|
||||
pcb.set_execute_path(path);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("path", format!("{:#x}", Self::path_ptr(args))),
|
||||
FormattedSyscallParam::new("argv", format!("{:#x}", Self::argv_ptr(args))),
|
||||
FormattedSyscallParam::new("env", format!("{:#x}", Self::env_ptr(args))),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_EXECVE, SysExecve);
|
34
kernel/src/process/syscall/sys_exit.rs
Normal file
34
kernel/src/process/syscall/sys_exit.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_EXIT;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysExit;
|
||||
|
||||
impl SysExit {
|
||||
fn exit_code(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysExit {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let exit_code = Self::exit_code(args);
|
||||
ProcessManager::exit((exit_code & 0xff) << 8);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"exit_code",
|
||||
format!("{:#x}", Self::exit_code(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_EXIT, SysExit);
|
34
kernel/src/process/syscall/sys_exit_group.rs
Normal file
34
kernel/src/process/syscall/sys_exit_group.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_EXIT_GROUP;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysExitGroup;
|
||||
|
||||
impl SysExitGroup {
|
||||
fn exit_code(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysExitGroup {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let exit_code = Self::exit_code(args);
|
||||
ProcessManager::exit((exit_code & 0xff) << 8);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"exit_code",
|
||||
format!("{:#x}", Self::exit_code(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_EXIT_GROUP, SysExitGroup);
|
26
kernel/src/process/syscall/sys_fork.rs
Normal file
26
kernel/src/process/syscall/sys_fork.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
//use crate::arch::syscall::nr::SYS_FORK;
|
||||
use crate::process::fork::CloneFlags;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysFork;
|
||||
|
||||
impl Syscall for SysFork {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
log::debug!("fork");
|
||||
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
//syscall_table_macros::declare_syscall!(SYS_FORK, SysFork);
|
52
kernel/src/process/syscall/sys_get_rusage.rs
Normal file
52
kernel/src/process/syscall/sys_get_rusage.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETRUSAGE;
|
||||
use crate::process::resource::RUsageWho;
|
||||
use crate::process::{resource::RUsage, ProcessManager};
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use crate::syscall::user_access::UserBufferWriter;
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::c_int;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysGetRusage;
|
||||
|
||||
impl SysGetRusage {
|
||||
fn who(args: &[usize]) -> c_int {
|
||||
args[0] as c_int
|
||||
}
|
||||
|
||||
fn rusage(args: &[usize]) -> *mut RUsage {
|
||||
args[1] as *mut RUsage
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysGetRusage {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let who = Self::who(args);
|
||||
let rusage = Self::rusage(args);
|
||||
|
||||
let who = RUsageWho::try_from(who)?;
|
||||
let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let ubuf = writer.buffer::<RUsage>(0).unwrap();
|
||||
ubuf.copy_from_slice(&[rusage]);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("who", format!("{:#x}", Self::who(args))),
|
||||
FormattedSyscallParam::new("rusage", format!("{:#x}", Self::rusage(args) as usize)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETRUSAGE, SysGetRusage);
|
26
kernel/src/process/syscall/sys_getegid.rs
Normal file
26
kernel/src/process/syscall/sys_getegid.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETEGID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysGetEgid;
|
||||
|
||||
impl Syscall for SysGetEgid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().egid.data());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETEGID, SysGetEgid);
|
25
kernel/src/process/syscall/sys_geteuid.rs
Normal file
25
kernel/src/process/syscall/sys_geteuid.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETEUID;
|
||||
use crate::process::geteuid::do_geteuid;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysGetEuid;
|
||||
|
||||
impl Syscall for SysGetEuid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
do_geteuid()
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETEUID, SysGetEuid);
|
25
kernel/src/process/syscall/sys_getgid.rs
Normal file
25
kernel/src/process/syscall/sys_getgid.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETGID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetGid;
|
||||
|
||||
impl Syscall for SysGetGid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().gid.data());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETGID, SysGetGid);
|
49
kernel/src/process/syscall/sys_getpgid.rs
Normal file
49
kernel/src/process/syscall/sys_getpgid.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETPGID;
|
||||
use crate::process::Pid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetPgid;
|
||||
|
||||
impl SysGetPgid {
|
||||
fn pid(args: &[usize]) -> Pid {
|
||||
Pid::new(args[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysGetPgid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 获取指定进程的pgid
|
||||
///
|
||||
/// ## 参数
|
||||
/// - pid: 指定一个进程号
|
||||
///
|
||||
/// ## 返回值
|
||||
/// - 成功,指定进程的进程组id
|
||||
/// - 错误,不存在该进程
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pid = Self::pid(args);
|
||||
if pid == Pid(0) {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
return Ok(current_pcb.pgid().into());
|
||||
}
|
||||
let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
return Ok(target_proc.pgid().into());
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"pid",
|
||||
format!("{:#x}", Self::pid(args).0),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETPGID, SysGetPgid);
|
33
kernel/src/process/syscall/sys_getpid.rs
Normal file
33
kernel/src/process/syscall/sys_getpid.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETPID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetPid;
|
||||
|
||||
impl Syscall for SysGetPid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 获取当前进程的pid
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
// if let Some(pid_ns) = ¤t_pcb.get_nsproxy().read().pid_namespace {
|
||||
// // 获取该进程在命名空间中的 PID
|
||||
// return Ok(current_pcb.pid_strcut().read().numbers[pid_ns.level].nr);
|
||||
// // 返回命名空间中的 PID
|
||||
// }
|
||||
// 默认返回 tgid
|
||||
return Ok(current_pcb.tgid().into());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETPID, SysGetPid);
|
27
kernel/src/process/syscall/sys_getppid.rs
Normal file
27
kernel/src/process/syscall/sys_getppid.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETPPID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetPpid;
|
||||
|
||||
impl Syscall for SysGetPpid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 获取当前进程的父进程id
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
return Ok(current_pcb.basic().ppid().into());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETPPID, SysGetPpid);
|
50
kernel/src/process/syscall/sys_getrlimit.rs
Normal file
50
kernel/src/process/syscall/sys_getrlimit.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETRLIMIT;
|
||||
use crate::process::resource::RLimit64;
|
||||
use crate::process::syscall::sys_prlimit64::do_prlimit64;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub struct SysGetRlimit;
|
||||
|
||||
impl SysGetRlimit {
|
||||
fn resource(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
|
||||
fn rlimit(args: &[usize]) -> *mut RLimit64 {
|
||||
args[1] as *mut RLimit64
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysGetRlimit {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let resource = Self::resource(args);
|
||||
let rlimit = Self::rlimit(args);
|
||||
|
||||
do_prlimit64(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
resource,
|
||||
core::ptr::null::<RLimit64>(),
|
||||
rlimit,
|
||||
)
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("resource", format!("{:#x}", Self::resource(args))),
|
||||
FormattedSyscallParam::new("rlimit", format!("{:#x}", Self::rlimit(args) as usize)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETRLIMIT, SysGetRlimit);
|
54
kernel/src/process/syscall/sys_getsid.rs
Normal file
54
kernel/src/process/syscall/sys_getsid.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETSID;
|
||||
use crate::process::Pid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetsid;
|
||||
|
||||
impl SysGetsid {
|
||||
fn pid(args: &[usize]) -> Pid {
|
||||
Pid::new(args[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysGetsid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 获取指定进程的会话id
|
||||
///
|
||||
/// 若pid为0,则返回当前进程的会话id
|
||||
///
|
||||
/// 若pid不为0,则返回指定进程的会话id
|
||||
///
|
||||
/// ## 参数
|
||||
/// - pid: 指定一个进程号
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pid = Self::pid(args);
|
||||
let session = ProcessManager::current_pcb().session().unwrap();
|
||||
let sid = session.sid().into();
|
||||
if pid == Pid(0) {
|
||||
return Ok(sid);
|
||||
}
|
||||
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
if !Arc::ptr_eq(&session, &pcb.session().unwrap()) {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
return Ok(sid);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"pid",
|
||||
format!("{:#x}", Self::pid(args).0),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETSID, SysGetsid);
|
25
kernel/src/process/syscall/sys_gettid.rs
Normal file
25
kernel/src/process/syscall/sys_gettid.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETTID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysGetTid;
|
||||
|
||||
impl Syscall for SysGetTid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.pid.into());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETTID, SysGetTid);
|
26
kernel/src/process/syscall/sys_getuid.rs
Normal file
26
kernel/src/process/syscall/sys_getuid.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_GETUID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysGetUid;
|
||||
|
||||
impl Syscall for SysGetUid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
return Ok(pcb.cred.lock().uid.data());
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_GETUID, SysGetUid);
|
135
kernel/src/process/syscall/sys_prlimit64.rs
Normal file
135
kernel/src/process/syscall/sys_prlimit64.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use crate::arch::syscall::nr::SYS_PRLIMIT64;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
filesystem::vfs::file::FileDescriptorVec,
|
||||
mm::{ucontext::UserStack, MemoryManagementArch},
|
||||
process::{
|
||||
resource::{RLimit64, RLimitID},
|
||||
Pid,
|
||||
},
|
||||
syscall::user_access::UserBufferWriter,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
pub struct SysPrlimit64;
|
||||
|
||||
impl SysPrlimit64 {
|
||||
fn pid(args: &[usize]) -> Pid {
|
||||
Pid::new(args[0])
|
||||
}
|
||||
|
||||
fn resource(args: &[usize]) -> usize {
|
||||
args[1]
|
||||
}
|
||||
|
||||
fn new_limit(args: &[usize]) -> *const RLimit64 {
|
||||
args[2] as *const RLimit64
|
||||
}
|
||||
|
||||
fn old_limit(args: &[usize]) -> *mut RLimit64 {
|
||||
args[3] as *mut RLimit64
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysPrlimit64 {
|
||||
fn num_args(&self) -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pid = Self::pid(args);
|
||||
let resource = Self::resource(args);
|
||||
let new_limit = Self::new_limit(args);
|
||||
let old_limit = Self::old_limit(args);
|
||||
|
||||
do_prlimit64(pid, resource, new_limit, old_limit)
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args).data())),
|
||||
FormattedSyscallParam::new("resource", format!("{:#x}", Self::resource(args))),
|
||||
FormattedSyscallParam::new(
|
||||
"new_limit",
|
||||
format!("{:#x}", Self::new_limit(args) as usize),
|
||||
),
|
||||
FormattedSyscallParam::new(
|
||||
"old_limit",
|
||||
format!("{:#x}", Self::old_limit(args) as usize),
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_PRLIMIT64, SysPrlimit64);
|
||||
|
||||
/// # 设置资源限制
|
||||
///
|
||||
/// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - pid: 进程号
|
||||
/// - resource: 资源类型
|
||||
/// - new_limit: 新的资源限制
|
||||
/// - old_limit: 旧的资源限制
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// - 成功,0
|
||||
/// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit
|
||||
///
|
||||
pub(super) fn do_prlimit64(
|
||||
_pid: Pid,
|
||||
resource: usize,
|
||||
_new_limit: *const RLimit64,
|
||||
old_limit: *mut RLimit64,
|
||||
) -> Result<usize, SystemError> {
|
||||
let resource = RLimitID::try_from(resource)?;
|
||||
let mut writer = None;
|
||||
|
||||
if !old_limit.is_null() {
|
||||
writer = Some(UserBufferWriter::new(
|
||||
old_limit,
|
||||
core::mem::size_of::<RLimit64>(),
|
||||
true,
|
||||
)?);
|
||||
}
|
||||
|
||||
match resource {
|
||||
RLimitID::Stack => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
|
||||
rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
RLimitID::Nofile => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
|
||||
rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
RLimitID::As | RLimitID::Rss => {
|
||||
if let Some(mut writer) = writer {
|
||||
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
|
||||
rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
|
||||
rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
}
|
||||
}
|
43
kernel/src/process/syscall/sys_set_tid_address.rs
Normal file
43
kernel/src/process/syscall/sys_set_tid_address.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SET_TID_ADDRESS;
|
||||
use crate::mm::verify_area;
|
||||
use crate::mm::VirtAddr;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetTidAddress;
|
||||
|
||||
impl SysSetTidAddress {
|
||||
fn ptr(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetTidAddress {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 设置线程地址
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let ptr = Self::ptr(args);
|
||||
verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>())
|
||||
.map_err(|_| SystemError::EFAULT)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
|
||||
Ok(pcb.pid.0)
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"ptr",
|
||||
format!("{:#x}", Self::ptr(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SET_TID_ADDRESS, SysSetTidAddress);
|
46
kernel/src/process/syscall/sys_setfsgid.rs
Normal file
46
kernel/src/process/syscall/sys_setfsgid.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETFSGID;
|
||||
use crate::process::cred::Kgid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysSetFsgid;
|
||||
|
||||
impl SysSetFsgid {
|
||||
fn fsgid(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetFsgid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let fsgid = Self::fsgid(args);
|
||||
let fsgid = Kgid::new(fsgid);
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
let old_fsgid = guard.fsgid;
|
||||
|
||||
if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid {
|
||||
guard.setfsgid(fsgid.data());
|
||||
}
|
||||
|
||||
Ok(old_fsgid.data())
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"fsgid",
|
||||
format!("{:#x}", Self::fsgid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETFSGID, SysSetFsgid);
|
45
kernel/src/process/syscall/sys_setfsuid.rs
Normal file
45
kernel/src/process/syscall/sys_setfsuid.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETFSUID;
|
||||
use crate::process::cred::Kuid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetFsuid;
|
||||
|
||||
impl SysSetFsuid {
|
||||
fn fsuid(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetFsuid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let fsuid = Self::fsuid(args);
|
||||
let fsuid = Kuid::new(fsuid);
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
let old_fsuid = guard.fsuid;
|
||||
|
||||
if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid {
|
||||
guard.setfsuid(fsuid.data());
|
||||
}
|
||||
|
||||
Ok(old_fsuid.data())
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"fsuid",
|
||||
format!("{:#x}", Self::fsuid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETFSUID, SysSetFsuid);
|
50
kernel/src/process/syscall/sys_setgid.rs
Normal file
50
kernel/src/process/syscall/sys_setgid.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETGID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysSetGid;
|
||||
|
||||
impl SysSetGid {
|
||||
fn gid(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetGid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let gid = Self::gid(args);
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if guard.egid.data() == 0 {
|
||||
guard.setgid(gid);
|
||||
guard.setegid(gid);
|
||||
guard.setsgid(gid);
|
||||
guard.setfsgid(gid);
|
||||
} else if guard.gid.data() == gid || guard.sgid.data() == gid {
|
||||
guard.setegid(gid);
|
||||
guard.setfsgid(gid);
|
||||
} else {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"gid",
|
||||
format!("{:#x}", Self::gid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETGID, SysSetGid);
|
69
kernel/src/process/syscall/sys_setpgid.rs
Normal file
69
kernel/src/process/syscall/sys_setpgid.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETPGID;
|
||||
use crate::process::Pgid;
|
||||
use crate::process::Pid;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetPgid;
|
||||
|
||||
impl SysSetPgid {
|
||||
fn pid(args: &[usize]) -> Pid {
|
||||
Pid::new(args[0])
|
||||
}
|
||||
|
||||
fn pgid(args: &[usize]) -> Pgid {
|
||||
Pgid::new(args[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetPgid {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 设置指定进程的pgid
|
||||
///
|
||||
/// ## 参数
|
||||
/// - pid: 指定进程号
|
||||
/// - pgid: 新的进程组号
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pid = Self::pid(args);
|
||||
let pgid = Self::pgid(args);
|
||||
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let pid = if pid == Pid(0) {
|
||||
current_pcb.pid()
|
||||
} else {
|
||||
pid
|
||||
};
|
||||
let pgid = if pgid == Pgid::from(0) {
|
||||
Pgid::from(pid.into())
|
||||
} else {
|
||||
pgid
|
||||
};
|
||||
if pid != current_pcb.pid() && !current_pcb.contain_child(&pid) {
|
||||
return Err(SystemError::ESRCH);
|
||||
}
|
||||
|
||||
if pgid.into() != pid.into() && ProcessManager::find_process_group(pgid).is_none() {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
|
||||
pcb.join_other_group(pgid)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args).0)),
|
||||
FormattedSyscallParam::new("pgid", format!("{:#x}", Self::pgid(args).0)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETPGID, SysSetPgid);
|
48
kernel/src/process/syscall/sys_setresgid.rs
Normal file
48
kernel/src/process/syscall/sys_setresgid.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETRESGID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetResGid;
|
||||
|
||||
impl SysSetResGid {
|
||||
fn egid(args: &[usize]) -> usize {
|
||||
args[1]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetResGid {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let egid = Self::egid(args);
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if egid != usize::MAX {
|
||||
guard.setegid(egid);
|
||||
}
|
||||
|
||||
let egid = guard.egid.data();
|
||||
guard.setfsgid(egid);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"egid",
|
||||
format!("{:#x}", Self::egid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETRESGID, SysSetResGid);
|
48
kernel/src/process/syscall/sys_setresuid.rs
Normal file
48
kernel/src/process/syscall/sys_setresuid.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETRESUID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetResUid;
|
||||
|
||||
impl SysSetResUid {
|
||||
fn euid(args: &[usize]) -> usize {
|
||||
args[1]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetResUid {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let euid = Self::euid(args);
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if euid != usize::MAX {
|
||||
guard.seteuid(euid);
|
||||
}
|
||||
|
||||
let euid = guard.euid.data();
|
||||
guard.setfsuid(euid);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"euid",
|
||||
format!("{:#x}", Self::euid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETRESUID, SysSetResUid);
|
30
kernel/src/process/syscall/sys_setsid.rs
Normal file
30
kernel/src/process/syscall/sys_setsid.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETSID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetsid;
|
||||
|
||||
impl Syscall for SysSetsid {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
/// # 函数的功能
|
||||
/// 创建新的会话
|
||||
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let session = pcb.go_to_new_session()?;
|
||||
let mut guard = pcb.sig_info_mut();
|
||||
guard.set_tty(None);
|
||||
Ok(session.sid().into())
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETSID, SysSetsid);
|
47
kernel/src/process/syscall/sys_setuid.rs
Normal file
47
kernel/src/process/syscall/sys_setuid.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_SETUID;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysSetUid;
|
||||
|
||||
impl SysSetUid {
|
||||
fn uid(args: &[usize]) -> usize {
|
||||
args[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSetUid {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let uid = Self::uid(args);
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut guard = pcb.cred.lock();
|
||||
|
||||
if guard.uid.data() == 0 {
|
||||
guard.setuid(uid);
|
||||
guard.seteuid(uid);
|
||||
guard.setsuid(uid);
|
||||
} else if uid == guard.uid.data() || uid == guard.suid.data() {
|
||||
guard.seteuid(uid);
|
||||
} else {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"uid",
|
||||
format!("{:#x}", Self::uid(args)),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_SETUID, SysSetUid);
|
38
kernel/src/process/syscall/sys_uname.rs
Normal file
38
kernel/src/process/syscall/sys_uname.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_UNAME;
|
||||
use crate::process::syscall::PosixOldUtsName;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use crate::syscall::user_access::UserBufferWriter;
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
pub struct SysUname;
|
||||
|
||||
impl SysUname {
|
||||
fn name(args: &[usize]) -> *mut PosixOldUtsName {
|
||||
args[0] as *mut PosixOldUtsName
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysUname {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let name = Self::name(args);
|
||||
let mut writer =
|
||||
UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?;
|
||||
writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"name",
|
||||
format!("{:#x}", Self::name(args) as usize),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_UNAME, SysUname);
|
35
kernel/src/process/syscall/sys_vfork.rs
Normal file
35
kernel/src/process/syscall/sys_vfork.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
//use crate::arch::syscall::nr::SYS_VFORK;
|
||||
use crate::process::fork::CloneFlags;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use alloc::vec::Vec;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysVfork;
|
||||
|
||||
impl Syscall for SysVfork {
|
||||
fn num_args(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
// 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit),
|
||||
// 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的)
|
||||
log::debug!("vfork");
|
||||
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
|
||||
|
||||
// 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏
|
||||
// ProcessManager::fork(
|
||||
// frame,
|
||||
// CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
|
||||
// )
|
||||
// .map(|pid| pid.into())
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
//syscall_table_macros::declare_syscall!(SYS_VFORK, SysVfork);
|
88
kernel/src/process/syscall/sys_wait4.rs
Normal file
88
kernel/src/process/syscall/sys_wait4.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_WAIT4;
|
||||
use crate::process::abi::WaitOption;
|
||||
use crate::process::exit::kernel_wait4;
|
||||
use crate::process::resource::RUsage;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use crate::syscall::user_access::UserBufferWriter;
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::c_int;
|
||||
use core::ffi::c_void;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysWait4;
|
||||
|
||||
impl SysWait4 {
|
||||
fn pid(args: &[usize]) -> i32 {
|
||||
args[0] as i32
|
||||
}
|
||||
|
||||
fn wstatus(args: &[usize]) -> *mut i32 {
|
||||
args[1] as *mut i32
|
||||
}
|
||||
|
||||
fn options(args: &[usize]) -> c_int {
|
||||
args[2] as c_int
|
||||
}
|
||||
|
||||
fn rusage(args: &[usize]) -> *mut c_void {
|
||||
args[3] as *mut c_void
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysWait4 {
|
||||
fn num_args(&self) -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
|
||||
let pid = Self::pid(args);
|
||||
let wstatus = Self::wstatus(args);
|
||||
let options = Self::options(args);
|
||||
let rusage = Self::rusage(args);
|
||||
// 权限校验
|
||||
// todo: 引入rusage之后,更正以下权限校验代码中,rusage的大小
|
||||
|
||||
let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let wstatus_buf = if wstatus.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(UserBufferWriter::new(
|
||||
wstatus,
|
||||
core::mem::size_of::<i32>(),
|
||||
true,
|
||||
)?)
|
||||
};
|
||||
|
||||
let mut tmp_rusage = if rusage.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(RUsage::default())
|
||||
};
|
||||
|
||||
let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?;
|
||||
|
||||
if !rusage.is_null() {
|
||||
let mut rusage_buf = UserBufferWriter::new::<RUsage>(
|
||||
rusage as *mut RUsage,
|
||||
core::mem::size_of::<RUsage>(),
|
||||
true,
|
||||
)?;
|
||||
rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?;
|
||||
}
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args))),
|
||||
FormattedSyscallParam::new("wstatus", format!("{:#x}", Self::wstatus(args) as usize)),
|
||||
FormattedSyscallParam::new("options", format!("{:#x}", Self::options(args))),
|
||||
FormattedSyscallParam::new("rusage", format!("{:#x}", Self::rusage(args) as usize)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_WAIT4, SysWait4);
|
@ -1,5 +1,6 @@
|
||||
use crate::process::fork::CloneFlags;
|
||||
use core::{
|
||||
ffi::{c_int, c_void},
|
||||
ffi::c_int,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
@ -9,12 +10,7 @@ use crate::{
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
|
||||
net::syscall::MsgHdr,
|
||||
process::{
|
||||
fork::KernelCloneArgs,
|
||||
process_group::Pgid,
|
||||
resource::{RLimit64, RUsage},
|
||||
ProcessFlags, ProcessManager,
|
||||
},
|
||||
process::{ProcessFlags, ProcessManager},
|
||||
sched::{schedule, SchedMode},
|
||||
syscall::user_access::check_and_clone_cstr,
|
||||
};
|
||||
@ -29,12 +25,10 @@ use crate::{
|
||||
filesystem::vfs::{
|
||||
fcntl::{AtFlags, FcntlCommand},
|
||||
syscall::{ModeType, UtimensFlags},
|
||||
MAX_PATHLEN,
|
||||
},
|
||||
libs::align::page_align_up,
|
||||
mm::{verify_area, MemoryManagementArch, VirtAddr},
|
||||
net::syscall::SockAddr,
|
||||
process::{fork::CloneFlags, syscall::PosixOldUtsName, Pid},
|
||||
time::{
|
||||
syscall::{PosixTimeZone, PosixTimeval},
|
||||
PosixTimeSpec,
|
||||
@ -106,6 +100,7 @@ impl Syscall {
|
||||
// handler.name,
|
||||
// handler.args_string(args)
|
||||
// );
|
||||
|
||||
return handler.inner_handle.handle(args, frame);
|
||||
}
|
||||
|
||||
@ -128,6 +123,11 @@ impl Syscall {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_FORK => ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_VFORK => ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()),
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_RENAMEAT => {
|
||||
let oldfd = args[0] as i32;
|
||||
@ -188,11 +188,6 @@ impl Syscall {
|
||||
Self::pwrite(fd, buf, len, offset)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_FORK => Self::fork(frame),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_VFORK => Self::vfork(frame),
|
||||
|
||||
SYS_BRK => {
|
||||
let new_brk = VirtAddr::new(args[0]);
|
||||
Self::brk(new_brk).map(|vaddr| vaddr.data())
|
||||
@ -243,44 +238,6 @@ impl Syscall {
|
||||
res
|
||||
}
|
||||
|
||||
SYS_EXECVE => {
|
||||
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 frame.is_from_user()
|
||||
&& (verify_area(virt_path_ptr, MAX_PATHLEN).is_err()
|
||||
|| verify_area(virt_argv_ptr, PAGE_4K_SIZE).is_err())
|
||||
|| verify_area(virt_env_ptr, PAGE_4K_SIZE).is_err()
|
||||
{
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
Self::execve(
|
||||
path_ptr as *const u8,
|
||||
argv_ptr as *const *const u8,
|
||||
env_ptr as *const *const u8,
|
||||
frame,
|
||||
)
|
||||
.map(|_| 0)
|
||||
}
|
||||
}
|
||||
SYS_WAIT4 => {
|
||||
let pid = args[0] as i32;
|
||||
let wstatus = args[1] as *mut i32;
|
||||
let options = args[2] as c_int;
|
||||
let rusage = args[3] as *mut c_void;
|
||||
// 权限校验
|
||||
// todo: 引入rusage之后,更正以下权限校验代码中,rusage的大小
|
||||
Self::wait4(pid, wstatus, options, rusage)
|
||||
}
|
||||
|
||||
SYS_EXIT => {
|
||||
let exit_code = args[0];
|
||||
Self::exit(exit_code)
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_MKDIR => {
|
||||
let path = args[0] as *const u8;
|
||||
@ -360,7 +317,6 @@ impl Syscall {
|
||||
let path = args[0] as *const u8;
|
||||
Self::unlink(path)
|
||||
}
|
||||
SYS_GETPID => Self::getpid().map(|pid| pid.into()),
|
||||
|
||||
SYS_SCHED => {
|
||||
warn!("syscall sched");
|
||||
@ -604,10 +560,6 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
|
||||
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pgid| pgid.into()),
|
||||
|
||||
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
|
||||
|
||||
SYS_FCNTL => {
|
||||
let fd = args[0] as i32;
|
||||
let cmd: Option<FcntlCommand> =
|
||||
@ -644,23 +596,6 @@ impl Syscall {
|
||||
)
|
||||
}
|
||||
|
||||
SYS_CLONE => {
|
||||
let parent_tid = VirtAddr::new(args[2]);
|
||||
let child_tid = VirtAddr::new(args[3]);
|
||||
|
||||
// 地址校验
|
||||
verify_area(parent_tid, core::mem::size_of::<i32>())?;
|
||||
verify_area(child_tid, core::mem::size_of::<i32>())?;
|
||||
|
||||
let mut clone_args = KernelCloneArgs::new();
|
||||
clone_args.flags = CloneFlags::from_bits_truncate(args[0] as u64);
|
||||
clone_args.stack = args[1];
|
||||
clone_args.parent_tid = parent_tid;
|
||||
clone_args.child_tid = child_tid;
|
||||
clone_args.tls = args[4];
|
||||
Self::clone(frame, clone_args)
|
||||
}
|
||||
|
||||
SYS_FUTEX => {
|
||||
let uaddr = VirtAddr::new(args[0]);
|
||||
let operation = FutexFlag::from_bits(args[1] as u32).ok_or(SystemError::ENOSYS)?;
|
||||
@ -703,8 +638,6 @@ impl Syscall {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]),
|
||||
|
||||
SYS_STATFS => {
|
||||
let path = args[0] as *const u8;
|
||||
let statfs = args[1] as *mut PosixStatfs;
|
||||
@ -751,12 +684,6 @@ impl Syscall {
|
||||
|
||||
SYS_PPOLL => Self::ppoll(args[0], args[1] as u32, args[2], args[3]),
|
||||
|
||||
SYS_SETPGID => {
|
||||
let pid = Pid::new(args[0]);
|
||||
let pgid = Pgid::new(args[1]);
|
||||
Self::setpgid(pid, pgid)
|
||||
}
|
||||
|
||||
SYS_TKILL => {
|
||||
warn!("SYS_TKILL has not yet been implemented");
|
||||
Ok(0)
|
||||
@ -767,13 +694,6 @@ impl Syscall {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
SYS_EXIT_GROUP => {
|
||||
let exit_code = args[0];
|
||||
Self::exit(exit_code)
|
||||
// warn!("SYS_EXIT_GROUP has not yet been implemented");
|
||||
// Ok(0)
|
||||
}
|
||||
|
||||
SYS_MADVISE => {
|
||||
let addr = args[0];
|
||||
let len = page_align_up(args[1]);
|
||||
@ -784,8 +704,6 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
|
||||
SYS_GETTID => Self::gettid().map(|tid| tid.into()),
|
||||
|
||||
SYS_SYSLOG => {
|
||||
let syslog_action_type = args[0];
|
||||
let buf_vaddr = args[1];
|
||||
@ -798,27 +716,6 @@ impl Syscall {
|
||||
Self::do_syslog(syslog_action_type, user_buf, len)
|
||||
}
|
||||
|
||||
SYS_GETUID => Self::getuid(),
|
||||
SYS_GETGID => Self::getgid(),
|
||||
SYS_SETUID => Self::setuid(args[0]),
|
||||
SYS_SETGID => Self::setgid(args[0]),
|
||||
|
||||
SYS_GETEUID => Self::geteuid(),
|
||||
SYS_GETEGID => Self::getegid(),
|
||||
SYS_SETRESUID => Self::seteuid(args[1]),
|
||||
SYS_SETRESGID => Self::setegid(args[1]),
|
||||
|
||||
SYS_SETFSUID => Self::setfsuid(args[0]),
|
||||
SYS_SETFSGID => Self::setfsgid(args[0]),
|
||||
|
||||
SYS_SETSID => Self::setsid(),
|
||||
SYS_GETSID => Self::getsid(Pid::new(args[0])),
|
||||
|
||||
SYS_GETRUSAGE => {
|
||||
let who = args[0] as c_int;
|
||||
let rusage = args[1] as *mut RUsage;
|
||||
Self::get_rusage(who, rusage)
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_READLINK => {
|
||||
let path = args[0] as *const u8;
|
||||
@ -835,16 +732,6 @@ impl Syscall {
|
||||
Self::readlink_at(dirfd, path, buf, bufsiz)
|
||||
}
|
||||
|
||||
SYS_PRLIMIT64 => {
|
||||
let pid = args[0];
|
||||
let pid = Pid::new(pid);
|
||||
let resource = args[1];
|
||||
let new_limit = args[2] as *const RLimit64;
|
||||
let old_limit = args[3] as *mut RLimit64;
|
||||
|
||||
Self::prlimit64(pid, resource, new_limit, old_limit)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_ACCESS => {
|
||||
let pathname = args[0] as *const u8;
|
||||
@ -954,19 +841,6 @@ impl Syscall {
|
||||
Self::getaffinity(pid, set)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_GETRLIMIT => {
|
||||
let resource = args[0];
|
||||
let rlimit = args[1] as *mut RLimit64;
|
||||
|
||||
Self::prlimit64(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
resource,
|
||||
core::ptr::null::<RLimit64>(),
|
||||
rlimit,
|
||||
)
|
||||
}
|
||||
|
||||
SYS_FADVISE64 => {
|
||||
// todo: 这个系统调用还没有实现
|
||||
|
||||
@ -993,10 +867,6 @@ impl Syscall {
|
||||
SYS_NEWFSTATAT => Self::newfstatat(args[0] as i32, args[1], args[2], args[3] as u32),
|
||||
|
||||
// SYS_SCHED_YIELD => Self::sched_yield(),
|
||||
SYS_UNAME => {
|
||||
let name = args[0] as *mut PosixOldUtsName;
|
||||
Self::uname(name)
|
||||
}
|
||||
SYS_PRCTL => {
|
||||
// todo: 这个系统调用还没有实现
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user