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 return Ok(current_pcb.tgid()); 192 } 193 194 /// @brief 获取指定进程的pgid 195 /// 196 /// @param pid 指定一个进程号 197 /// 198 /// @return 成功,指定进程的进程组id 199 /// @return 错误,不存在该进程 200 pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 201 if pid == Pid(0) { 202 let current_pcb = ProcessManager::current_pcb(); 203 pid = current_pcb.pid(); 204 } 205 let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 206 return Ok(target_proc.basic().pgid()); 207 } 208 /// @brief 获取当前进程的父进程id 209 210 /// 若为initproc则ppid设置为0 211 pub fn getppid() -> Result<Pid, SystemError> { 212 let current_pcb = ProcessManager::current_pcb(); 213 return Ok(current_pcb.basic().ppid()); 214 } 215 216 pub fn clone( 217 current_trapframe: &TrapFrame, 218 clone_args: KernelCloneArgs, 219 ) -> Result<usize, SystemError> { 220 let flags = clone_args.flags; 221 222 let vfork = Arc::new(Completion::new()); 223 224 if flags.contains(CloneFlags::CLONE_PIDFD) 225 && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 226 { 227 return Err(SystemError::EINVAL); 228 } 229 230 let current_pcb = ProcessManager::current_pcb(); 231 let new_kstack = KernelStack::new()?; 232 let name = current_pcb.basic().name().to_string(); 233 let pcb = ProcessControlBlock::new(name, new_kstack); 234 // 克隆pcb 235 ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 236 ProcessManager::add_pcb(pcb.clone()); 237 238 // 向procfs注册进程 239 procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 240 panic!( 241 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 242 pcb.pid(), 243 e 244 ) 245 }); 246 247 if flags.contains(CloneFlags::CLONE_VFORK) { 248 pcb.thread.write_irqsave().vfork_done = Some(vfork.clone()); 249 } 250 251 if pcb.thread.read_irqsave().set_child_tid.is_some() { 252 let addr = pcb.thread.read_irqsave().set_child_tid.unwrap(); 253 let mut writer = 254 UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 255 writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 256 } 257 258 ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 259 panic!( 260 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 261 pcb.pid(), 262 e 263 ) 264 }); 265 266 if flags.contains(CloneFlags::CLONE_VFORK) { 267 // 等待子进程结束或者exec; 268 vfork.wait_for_completion_interruptible()?; 269 } 270 271 return Ok(pcb.pid().0); 272 } 273 274 /// 设置线程地址 275 pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 276 verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>()) 277 .map_err(|_| SystemError::EFAULT)?; 278 279 let pcb = ProcessManager::current_pcb(); 280 pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr)); 281 Ok(pcb.pid.0) 282 } 283 284 pub fn gettid() -> Result<Pid, SystemError> { 285 let pcb = ProcessManager::current_pcb(); 286 Ok(pcb.pid) 287 } 288 289 pub fn getuid() -> Result<usize, SystemError> { 290 let pcb = ProcessManager::current_pcb(); 291 return Ok(pcb.cred.lock().uid.data()); 292 } 293 294 pub fn getgid() -> Result<usize, SystemError> { 295 let pcb = ProcessManager::current_pcb(); 296 return Ok(pcb.cred.lock().gid.data()); 297 } 298 299 pub fn geteuid() -> Result<usize, SystemError> { 300 let pcb = ProcessManager::current_pcb(); 301 return Ok(pcb.cred.lock().euid.data()); 302 } 303 304 pub fn getegid() -> Result<usize, SystemError> { 305 let pcb = ProcessManager::current_pcb(); 306 return Ok(pcb.cred.lock().egid.data()); 307 } 308 309 pub fn setuid(uid: usize) -> Result<usize, SystemError> { 310 let pcb = ProcessManager::current_pcb(); 311 let mut guard = pcb.cred.lock(); 312 313 if guard.uid.data() == 0 { 314 guard.setuid(uid); 315 guard.seteuid(uid); 316 guard.setsuid(uid); 317 } else if uid == guard.uid.data() || uid == guard.suid.data() { 318 guard.seteuid(uid); 319 } else { 320 return Err(SystemError::EPERM); 321 } 322 323 return Ok(0); 324 } 325 326 pub fn setgid(gid: usize) -> Result<usize, SystemError> { 327 let pcb = ProcessManager::current_pcb(); 328 let mut guard = pcb.cred.lock(); 329 330 if guard.egid.data() == 0 { 331 guard.setgid(gid); 332 guard.setegid(gid); 333 guard.setsgid(gid); 334 guard.setfsgid(gid); 335 } else if guard.gid.data() == gid || guard.sgid.data() == gid { 336 guard.setegid(gid); 337 guard.setfsgid(gid); 338 } else { 339 return Err(SystemError::EPERM); 340 } 341 342 return Ok(0); 343 } 344 345 pub fn seteuid(euid: usize) -> Result<usize, SystemError> { 346 let pcb = ProcessManager::current_pcb(); 347 let mut guard = pcb.cred.lock(); 348 349 if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) { 350 return Ok(0); 351 } 352 353 if euid != usize::MAX { 354 guard.seteuid(euid); 355 } 356 357 let euid = guard.euid.data(); 358 guard.setfsuid(euid); 359 360 return Ok(0); 361 } 362 363 pub fn setegid(egid: usize) -> Result<usize, SystemError> { 364 let pcb = ProcessManager::current_pcb(); 365 let mut guard = pcb.cred.lock(); 366 367 if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) { 368 return Ok(0); 369 } 370 371 if egid != usize::MAX { 372 guard.setegid(egid); 373 } 374 375 let egid = guard.egid.data(); 376 guard.setfsgid(egid); 377 378 return Ok(0); 379 } 380 381 pub fn setfsuid(fsuid: usize) -> Result<usize, SystemError> { 382 let fsuid = Kuid::new(fsuid); 383 384 let pcb = ProcessManager::current_pcb(); 385 let mut guard = pcb.cred.lock(); 386 let old_fsuid = guard.fsuid; 387 388 if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid { 389 guard.setfsuid(fsuid.data()); 390 } 391 392 Ok(old_fsuid.data()) 393 } 394 395 pub fn setfsgid(fsgid: usize) -> Result<usize, SystemError> { 396 let fsgid = Kgid::new(fsgid); 397 398 let pcb = ProcessManager::current_pcb(); 399 let mut guard = pcb.cred.lock(); 400 let old_fsgid = guard.fsgid; 401 402 if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid { 403 guard.setfsgid(fsgid.data()); 404 } 405 406 Ok(old_fsgid.data()) 407 } 408 409 pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> { 410 let who = RUsageWho::try_from(who)?; 411 let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?; 412 let pcb = ProcessManager::current_pcb(); 413 let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?; 414 415 let ubuf = writer.buffer::<RUsage>(0).unwrap(); 416 ubuf.copy_from_slice(&[rusage]); 417 418 return Ok(0); 419 } 420 421 /// # 设置资源限制 422 /// 423 /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能 424 /// 425 /// ## 参数 426 /// 427 /// - pid: 进程号 428 /// - resource: 资源类型 429 /// - new_limit: 新的资源限制 430 /// - old_limit: 旧的资源限制 431 /// 432 /// ## 返回值 433 /// 434 /// - 成功,0 435 /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit 436 /// 437 pub fn prlimit64( 438 _pid: Pid, 439 resource: usize, 440 _new_limit: *const RLimit64, 441 old_limit: *mut RLimit64, 442 ) -> Result<usize, SystemError> { 443 let resource = RLimitID::try_from(resource)?; 444 let mut writer = None; 445 446 if !old_limit.is_null() { 447 writer = Some(UserBufferWriter::new( 448 old_limit, 449 core::mem::size_of::<RLimit64>(), 450 true, 451 )?); 452 } 453 454 match resource { 455 RLimitID::Stack => { 456 if let Some(mut writer) = writer { 457 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 458 rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64; 459 rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64; 460 } 461 return Ok(0); 462 } 463 464 RLimitID::Nofile => { 465 if let Some(mut writer) = writer { 466 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 467 rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64; 468 rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64; 469 } 470 return Ok(0); 471 } 472 473 RLimitID::As | RLimitID::Rss => { 474 if let Some(mut writer) = writer { 475 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 476 rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64; 477 rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64; 478 } 479 return Ok(0); 480 } 481 482 _ => { 483 return Err(SystemError::ENOSYS); 484 } 485 } 486 } 487 488 pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> { 489 let mut writer = 490 UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?; 491 writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?; 492 493 return Ok(0); 494 } 495 } 496