xref: /DragonOS/kernel/src/process/syscall.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
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) = &current_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(&current_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