syscall.rs 16 KB

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