1 use core::ffi::c_void; 2 3 use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec}; 4 use log::error; 5 use system_error::SystemError; 6 7 use super::{ 8 abi::WaitOption, 9 cred::{Kgid, Kuid}, 10 exit::kernel_wait4, 11 fork::{CloneFlags, KernelCloneArgs}, 12 resource::{RLimit64, RLimitID, RUsage, RUsageWho}, 13 KernelStack, Pid, ProcessManager, 14 }; 15 use crate::{ 16 arch::{interrupt::TrapFrame, MMArch}, 17 filesystem::{ 18 procfs::procfs_register_pid, 19 vfs::{file::FileDescriptorVec, MAX_PATHLEN}, 20 }, 21 mm::{ucontext::UserStack, verify_area, MemoryManagementArch, VirtAddr}, 22 process::ProcessControlBlock, 23 sched::completion::Completion, 24 syscall::{ 25 user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter}, 26 Syscall, 27 }, 28 }; 29 30 //参考资料:https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17 31 #[repr(C)] 32 #[derive(Debug, Clone, Copy)] 33 pub struct PosixOldUtsName { 34 pub sysname: [u8; 65], 35 pub nodename: [u8; 65], 36 pub release: [u8; 65], 37 pub version: [u8; 65], 38 pub machine: [u8; 65], 39 } 40 41 impl PosixOldUtsName { 42 pub fn new() -> Self { 43 const SYS_NAME: &[u8] = b"DragonOS"; 44 const NODENAME: &[u8] = b"DragonOS"; 45 const RELEASE: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 46 const VERSION: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 47 48 #[cfg(target_arch = "x86_64")] 49 const MACHINE: &[u8] = b"x86_64"; 50 51 #[cfg(target_arch = "aarch64")] 52 const MACHINE: &[u8] = b"aarch64"; 53 54 #[cfg(target_arch = "riscv64")] 55 const MACHINE: &[u8] = b"riscv64"; 56 57 let mut r = Self { 58 sysname: [0; 65], 59 nodename: [0; 65], 60 release: [0; 65], 61 version: [0; 65], 62 machine: [0; 65], 63 }; 64 65 r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME); 66 r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME); 67 r.release[0..RELEASE.len()].copy_from_slice(RELEASE); 68 r.version[0..VERSION.len()].copy_from_slice(VERSION); 69 r.machine[0..MACHINE.len()].copy_from_slice(MACHINE); 70 71 return r; 72 } 73 } 74 75 impl Syscall { 76 pub fn fork(frame: &TrapFrame) -> Result<usize, SystemError> { 77 ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()) 78 } 79 80 pub fn vfork(frame: &TrapFrame) -> Result<usize, SystemError> { 81 // 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit), 82 // 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的) 83 Self::fork(frame) 84 85 // 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏 86 // ProcessManager::fork( 87 // frame, 88 // CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 89 // ) 90 // .map(|pid| pid.into()) 91 } 92 93 pub fn execve( 94 path: *const u8, 95 argv: *const *const u8, 96 envp: *const *const u8, 97 frame: &mut TrapFrame, 98 ) -> Result<(), SystemError> { 99 // debug!( 100 // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 101 // path, 102 // argv, 103 // envp 104 // ); 105 // debug!( 106 // "before execve: strong count: {}", 107 // Arc::strong_count(&ProcessManager::current_pcb()) 108 // ); 109 110 if path.is_null() { 111 return Err(SystemError::EINVAL); 112 } 113 114 let x = || { 115 let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 116 let argv: Vec<CString> = check_and_clone_cstr_array(argv)?; 117 let envp: Vec<CString> = check_and_clone_cstr_array(envp)?; 118 Ok((path, argv, envp)) 119 }; 120 let (path, argv, envp) = x().inspect_err(|e: &SystemError| { 121 error!("Failed to execve: {:?}", e); 122 })?; 123 124 let path = path.into_string().map_err(|_| SystemError::EINVAL)?; 125 ProcessManager::current_pcb() 126 .basic_mut() 127 .set_name(ProcessControlBlock::generate_name(&path, &argv)); 128 129 Self::do_execve(path, argv, envp, frame)?; 130 131 // 关闭设置了O_CLOEXEC的文件描述符 132 let fd_table = ProcessManager::current_pcb().fd_table(); 133 fd_table.write().close_on_exec(); 134 // debug!( 135 // "after execve: strong count: {}", 136 // Arc::strong_count(&ProcessManager::current_pcb()) 137 // ); 138 139 return Ok(()); 140 } 141 142 pub fn wait4( 143 pid: i64, 144 wstatus: *mut i32, 145 options: i32, 146 rusage: *mut c_void, 147 ) -> Result<usize, SystemError> { 148 let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?; 149 150 let wstatus_buf = if wstatus.is_null() { 151 None 152 } else { 153 Some(UserBufferWriter::new( 154 wstatus, 155 core::mem::size_of::<i32>(), 156 true, 157 )?) 158 }; 159 160 let mut tmp_rusage = if rusage.is_null() { 161 None 162 } else { 163 Some(RUsage::default()) 164 }; 165 166 let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?; 167 168 if !rusage.is_null() { 169 let mut rusage_buf = UserBufferWriter::new::<RUsage>( 170 rusage as *mut RUsage, 171 core::mem::size_of::<RUsage>(), 172 true, 173 )?; 174 rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?; 175 } 176 return Ok(r); 177 } 178 179 /// # 退出进程 180 /// 181 /// ## 参数 182 /// 183 /// - status: 退出状态 184 pub fn exit(status: usize) -> ! { 185 ProcessManager::exit(status); 186 } 187 188 /// @brief 获取当前进程的pid 189 pub fn getpid() -> Result<Pid, SystemError> { 190 let current_pcb = ProcessManager::current_pcb(); 191 // if let Some(pid_ns) = ¤t_pcb.get_nsproxy().read().pid_namespace { 192 // // 获取该进程在命名空间中的 PID 193 // return Ok(current_pcb.pid_strcut().read().numbers[pid_ns.level].nr); 194 // // 返回命名空间中的 PID 195 // } 196 // 默认返回 tgid 197 Ok(current_pcb.tgid()) 198 } 199 200 /// @brief 获取指定进程的pgid 201 /// 202 /// @param pid 指定一个进程号 203 /// 204 /// @return 成功,指定进程的进程组id 205 /// @return 错误,不存在该进程 206 pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 207 if pid == Pid(0) { 208 let current_pcb = ProcessManager::current_pcb(); 209 pid = current_pcb.pid(); 210 } 211 let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 212 return Ok(target_proc.basic().pgid()); 213 } 214 /// @brief 获取当前进程的父进程id 215 /// 216 /// 若为initproc则ppid设置为0 217 pub fn getppid() -> Result<Pid, SystemError> { 218 let current_pcb = ProcessManager::current_pcb(); 219 return Ok(current_pcb.basic().ppid()); 220 } 221 222 pub fn clone( 223 current_trapframe: &TrapFrame, 224 clone_args: KernelCloneArgs, 225 ) -> Result<usize, SystemError> { 226 let flags = clone_args.flags; 227 228 let vfork = Arc::new(Completion::new()); 229 230 if flags.contains(CloneFlags::CLONE_PIDFD) 231 && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 232 { 233 return Err(SystemError::EINVAL); 234 } 235 236 let current_pcb = ProcessManager::current_pcb(); 237 let new_kstack = KernelStack::new()?; 238 let name = current_pcb.basic().name().to_string(); 239 let pcb = ProcessControlBlock::new(name, new_kstack); 240 // 克隆pcb 241 ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 242 ProcessManager::add_pcb(pcb.clone()); 243 244 // 向procfs注册进程 245 procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 246 panic!( 247 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 248 pcb.pid(), 249 e 250 ) 251 }); 252 253 if flags.contains(CloneFlags::CLONE_VFORK) { 254 pcb.thread.write_irqsave().vfork_done = Some(vfork.clone()); 255 } 256 257 if pcb.thread.read_irqsave().set_child_tid.is_some() { 258 let addr = pcb.thread.read_irqsave().set_child_tid.unwrap(); 259 let mut writer = 260 UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 261 writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 262 } 263 264 ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 265 panic!( 266 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 267 pcb.pid(), 268 e 269 ) 270 }); 271 272 if flags.contains(CloneFlags::CLONE_VFORK) { 273 // 等待子进程结束或者exec; 274 vfork.wait_for_completion_interruptible()?; 275 } 276 277 return Ok(pcb.pid().0); 278 } 279 280 /// 设置线程地址 281 pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 282 verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>()) 283 .map_err(|_| SystemError::EFAULT)?; 284 285 let pcb = ProcessManager::current_pcb(); 286 pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr)); 287 Ok(pcb.pid.0) 288 } 289 290 pub fn gettid() -> Result<Pid, SystemError> { 291 let pcb = ProcessManager::current_pcb(); 292 Ok(pcb.pid) 293 } 294 295 pub fn getuid() -> Result<usize, SystemError> { 296 let pcb = ProcessManager::current_pcb(); 297 return Ok(pcb.cred.lock().uid.data()); 298 } 299 300 pub fn getgid() -> Result<usize, SystemError> { 301 let pcb = ProcessManager::current_pcb(); 302 return Ok(pcb.cred.lock().gid.data()); 303 } 304 305 pub fn geteuid() -> Result<usize, SystemError> { 306 let pcb = ProcessManager::current_pcb(); 307 return Ok(pcb.cred.lock().euid.data()); 308 } 309 310 pub fn getegid() -> Result<usize, SystemError> { 311 let pcb = ProcessManager::current_pcb(); 312 return Ok(pcb.cred.lock().egid.data()); 313 } 314 315 pub fn setuid(uid: usize) -> Result<usize, SystemError> { 316 let pcb = ProcessManager::current_pcb(); 317 let mut guard = pcb.cred.lock(); 318 319 if guard.uid.data() == 0 { 320 guard.setuid(uid); 321 guard.seteuid(uid); 322 guard.setsuid(uid); 323 } else if uid == guard.uid.data() || uid == guard.suid.data() { 324 guard.seteuid(uid); 325 } else { 326 return Err(SystemError::EPERM); 327 } 328 329 return Ok(0); 330 } 331 332 pub fn setgid(gid: usize) -> Result<usize, SystemError> { 333 let pcb = ProcessManager::current_pcb(); 334 let mut guard = pcb.cred.lock(); 335 336 if guard.egid.data() == 0 { 337 guard.setgid(gid); 338 guard.setegid(gid); 339 guard.setsgid(gid); 340 guard.setfsgid(gid); 341 } else if guard.gid.data() == gid || guard.sgid.data() == gid { 342 guard.setegid(gid); 343 guard.setfsgid(gid); 344 } else { 345 return Err(SystemError::EPERM); 346 } 347 348 return Ok(0); 349 } 350 351 pub fn seteuid(euid: usize) -> Result<usize, SystemError> { 352 let pcb = ProcessManager::current_pcb(); 353 let mut guard = pcb.cred.lock(); 354 355 if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) { 356 return Ok(0); 357 } 358 359 if euid != usize::MAX { 360 guard.seteuid(euid); 361 } 362 363 let euid = guard.euid.data(); 364 guard.setfsuid(euid); 365 366 return Ok(0); 367 } 368 369 pub fn setegid(egid: usize) -> Result<usize, SystemError> { 370 let pcb = ProcessManager::current_pcb(); 371 let mut guard = pcb.cred.lock(); 372 373 if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) { 374 return Ok(0); 375 } 376 377 if egid != usize::MAX { 378 guard.setegid(egid); 379 } 380 381 let egid = guard.egid.data(); 382 guard.setfsgid(egid); 383 384 return Ok(0); 385 } 386 387 pub fn setfsuid(fsuid: usize) -> Result<usize, SystemError> { 388 let fsuid = Kuid::new(fsuid); 389 390 let pcb = ProcessManager::current_pcb(); 391 let mut guard = pcb.cred.lock(); 392 let old_fsuid = guard.fsuid; 393 394 if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid { 395 guard.setfsuid(fsuid.data()); 396 } 397 398 Ok(old_fsuid.data()) 399 } 400 401 pub fn setfsgid(fsgid: usize) -> Result<usize, SystemError> { 402 let fsgid = Kgid::new(fsgid); 403 404 let pcb = ProcessManager::current_pcb(); 405 let mut guard = pcb.cred.lock(); 406 let old_fsgid = guard.fsgid; 407 408 if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid { 409 guard.setfsgid(fsgid.data()); 410 } 411 412 Ok(old_fsgid.data()) 413 } 414 415 pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> { 416 let who = RUsageWho::try_from(who)?; 417 let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?; 418 let pcb = ProcessManager::current_pcb(); 419 let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?; 420 421 let ubuf = writer.buffer::<RUsage>(0).unwrap(); 422 ubuf.copy_from_slice(&[rusage]); 423 424 return Ok(0); 425 } 426 427 /// # 设置资源限制 428 /// 429 /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能 430 /// 431 /// ## 参数 432 /// 433 /// - pid: 进程号 434 /// - resource: 资源类型 435 /// - new_limit: 新的资源限制 436 /// - old_limit: 旧的资源限制 437 /// 438 /// ## 返回值 439 /// 440 /// - 成功,0 441 /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit 442 /// 443 pub fn prlimit64( 444 _pid: Pid, 445 resource: usize, 446 _new_limit: *const RLimit64, 447 old_limit: *mut RLimit64, 448 ) -> Result<usize, SystemError> { 449 let resource = RLimitID::try_from(resource)?; 450 let mut writer = None; 451 452 if !old_limit.is_null() { 453 writer = Some(UserBufferWriter::new( 454 old_limit, 455 core::mem::size_of::<RLimit64>(), 456 true, 457 )?); 458 } 459 460 match resource { 461 RLimitID::Stack => { 462 if let Some(mut writer) = writer { 463 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 464 rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64; 465 rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64; 466 } 467 return Ok(0); 468 } 469 470 RLimitID::Nofile => { 471 if let Some(mut writer) = writer { 472 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 473 rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64; 474 rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64; 475 } 476 return Ok(0); 477 } 478 479 RLimitID::As | RLimitID::Rss => { 480 if let Some(mut writer) = writer { 481 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 482 rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64; 483 rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64; 484 } 485 return Ok(0); 486 } 487 488 _ => { 489 return Err(SystemError::ENOSYS); 490 } 491 } 492 } 493 494 pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> { 495 let mut writer = 496 UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?; 497 writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?; 498 499 return Ok(0); 500 } 501 } 502