procops.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. use super::sysinfo::TimeVal;
  2. use super::SyscallNoReturn;
  3. use crate::elf::ParsedElf32;
  4. use crate::io::Buffer;
  5. use crate::kernel::constants::{
  6. ENOSYS, PR_GET_NAME, PR_SET_NAME, RLIMIT_STACK, SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK,
  7. };
  8. use crate::kernel::mem::PageBuffer;
  9. use crate::kernel::task::{
  10. KernelStack, ProcessBuilder, ProcessList, Signal, SignalAction, SignalMask, ThreadBuilder,
  11. ThreadRunnable, UserDescriptor, WaitObject, WaitType,
  12. };
  13. use crate::kernel::user::dataflow::UserString;
  14. use crate::kernel::user::{UserPointer, UserPointerMut};
  15. use crate::kernel::vfs::{self, dentry::Dentry};
  16. use crate::path::Path;
  17. use crate::SIGNAL_NOW;
  18. use crate::{kernel::user::dataflow::UserBuffer, prelude::*};
  19. use alloc::borrow::ToOwned;
  20. use alloc::ffi::CString;
  21. use bindings::{EINVAL, ENOENT, ENOTDIR, ERANGE, ESRCH};
  22. use bitflags::bitflags;
  23. use eonix_hal::traits::trap::RawTrapContext;
  24. use eonix_mm::address::Addr as _;
  25. use eonix_runtime::scheduler::Scheduler;
  26. use eonix_runtime::task::Task;
  27. use eonix_sync::AsProof as _;
  28. use posix_types::signal::SigAction;
  29. #[repr(C)]
  30. #[derive(Debug, Clone, Copy)]
  31. struct RLimit {
  32. rlim_cur: u64,
  33. rlim_max: u64,
  34. }
  35. bitflags! {
  36. pub struct UserWaitOptions: u32 {
  37. const WNOHANG = 1;
  38. const WUNTRACED = 2;
  39. const WCONTINUED = 8;
  40. }
  41. }
  42. #[eonix_macros::define_syscall(0x3c)]
  43. fn umask(mask: u32) -> KResult<u32> {
  44. let mut umask = thread.fs_context.umask.lock();
  45. let old = *umask;
  46. *umask = mask & 0o777;
  47. Ok(old)
  48. }
  49. #[eonix_macros::define_syscall(0xb7)]
  50. fn getcwd(buffer: *mut u8, bufsize: usize) -> KResult<usize> {
  51. let mut user_buffer = UserBuffer::new(buffer, bufsize)?;
  52. let mut buffer = PageBuffer::new();
  53. thread
  54. .fs_context
  55. .cwd
  56. .lock()
  57. .get_path(&thread.fs_context, &mut buffer)?;
  58. user_buffer.fill(buffer.data())?.ok_or(ERANGE)?;
  59. Ok(buffer.wrote())
  60. }
  61. #[eonix_macros::define_syscall(0x0c)]
  62. fn chdir(path: *const u8) -> KResult<()> {
  63. let path = UserString::new(path)?;
  64. let path = Path::new(path.as_cstr().to_bytes())?;
  65. let dentry = Dentry::open(&thread.fs_context, path, true)?;
  66. if !dentry.is_valid() {
  67. return Err(ENOENT);
  68. }
  69. if !dentry.is_directory() {
  70. return Err(ENOTDIR);
  71. }
  72. *thread.fs_context.cwd.lock() = dentry;
  73. Ok(())
  74. }
  75. #[eonix_macros::define_syscall(0x15)]
  76. fn mount(source: *const u8, target: *const u8, fstype: *const u8, flags: usize) -> KResult<()> {
  77. let source = UserString::new(source)?;
  78. let target = UserString::new(target)?;
  79. let fstype = UserString::new(fstype)?;
  80. let mountpoint = Dentry::open(
  81. &thread.fs_context,
  82. Path::new(target.as_cstr().to_bytes())?,
  83. true,
  84. )?;
  85. if !mountpoint.is_valid() {
  86. return Err(ENOENT);
  87. }
  88. vfs::mount::do_mount(
  89. &mountpoint,
  90. source.as_cstr().to_str().map_err(|_| EINVAL)?,
  91. target.as_cstr().to_str().map_err(|_| EINVAL)?,
  92. fstype.as_cstr().to_str().map_err(|_| EINVAL)?,
  93. flags as u64,
  94. )
  95. }
  96. fn get_strings(mut ptr_strings: UserPointer<'_, u32>) -> KResult<Vec<CString>> {
  97. let mut strings = Vec::new();
  98. loop {
  99. let addr = ptr_strings.read()?;
  100. if addr == 0 {
  101. break;
  102. }
  103. let user_string = UserString::new(addr as *const u8)?;
  104. strings.push(user_string.as_cstr().to_owned());
  105. ptr_strings = ptr_strings.offset(1)?;
  106. }
  107. Ok(strings)
  108. }
  109. #[eonix_macros::define_syscall(0x0b)]
  110. fn execve(exec: *const u8, argv: *const u32, envp: *const u32) -> KResult<()> {
  111. let exec = UserString::new(exec)?;
  112. let argv = get_strings(UserPointer::new(argv)?)?;
  113. let envp = get_strings(UserPointer::new(envp)?)?;
  114. let dentry = Dentry::open(
  115. &thread.fs_context,
  116. Path::new(exec.as_cstr().to_bytes())?,
  117. true,
  118. )?;
  119. if !dentry.is_valid() {
  120. Err(ENOENT)?;
  121. }
  122. // TODO: When `execve` is called by one of the threads in a process, the other threads
  123. // should be terminated and `execve` is performed in the thread group leader.
  124. let elf = ParsedElf32::parse(dentry.clone())?;
  125. if let Ok((ip, sp, mm_list)) = elf.load(argv, envp) {
  126. unsafe {
  127. // SAFETY: We are doing execve, all other threads are terminated.
  128. thread.process.mm_list.replace(Some(mm_list));
  129. }
  130. thread.files.on_exec();
  131. thread.signal_list.clear_non_ignore();
  132. thread.set_name(dentry.name().clone());
  133. let mut trap_ctx = thread.trap_ctx.borrow();
  134. trap_ctx.set_program_counter(ip.addr());
  135. trap_ctx.set_stack_pointer(sp.addr());
  136. Ok(())
  137. } else {
  138. // We can't hold any ownership when we call `kill_current`.
  139. // ProcessList::kill_current(Signal::SIGSEGV);
  140. todo!()
  141. }
  142. }
  143. #[eonix_macros::define_syscall(0x01)]
  144. fn exit(status: u32) {
  145. unsafe {
  146. let mut procs = Task::block_on(ProcessList::get().write());
  147. procs.do_kill_process(&thread.process, WaitType::Exited(status));
  148. }
  149. todo!()
  150. }
  151. #[eonix_macros::define_syscall(0xfc)]
  152. fn exit_group(status: u32) {
  153. sys_exit(thread, status)
  154. }
  155. #[eonix_macros::define_syscall(0x07)]
  156. fn waitpid(_waitpid: u32, arg1: *mut u32, options: u32) -> KResult<u32> {
  157. // if waitpid != u32::MAX {
  158. // unimplemented!("waitpid with pid {waitpid}")
  159. // }
  160. let options = match UserWaitOptions::from_bits(options) {
  161. None => unimplemented!("waitpid with options {options}"),
  162. Some(options) => options,
  163. };
  164. let wait_object = Task::block_on(thread.process.wait(
  165. options.contains(UserWaitOptions::WNOHANG),
  166. options.contains(UserWaitOptions::WUNTRACED),
  167. options.contains(UserWaitOptions::WCONTINUED),
  168. ))?;
  169. match wait_object {
  170. None => Ok(0),
  171. Some(WaitObject { pid, code }) => {
  172. if !arg1.is_null() {
  173. UserPointerMut::new(arg1)?.write(code.to_wstatus())?;
  174. }
  175. Ok(pid)
  176. }
  177. }
  178. }
  179. #[eonix_macros::define_syscall(0x72)]
  180. fn wait4(waitpid: u32, arg1: *mut u32, options: u32, rusage: *mut ()) -> KResult<u32> {
  181. if rusage.is_null() {
  182. sys_waitpid(thread, waitpid, arg1, options)
  183. } else {
  184. unimplemented!("wait4 with rusage")
  185. }
  186. }
  187. #[eonix_macros::define_syscall(0x42)]
  188. fn setsid() -> KResult<u32> {
  189. thread.process.setsid()
  190. }
  191. #[eonix_macros::define_syscall(0x39)]
  192. fn setpgid(pid: u32, pgid: i32) -> KResult<()> {
  193. let pid = if pid == 0 { thread.process.pid } else { pid };
  194. let pgid = match pgid {
  195. 0 => pid,
  196. 1.. => pgid as u32,
  197. _ => return Err(EINVAL),
  198. };
  199. thread.process.setpgid(pid, pgid)
  200. }
  201. #[eonix_macros::define_syscall(0x93)]
  202. fn getsid(pid: u32) -> KResult<u32> {
  203. if pid == 0 {
  204. Ok(thread.process.session_rcu().sid)
  205. } else {
  206. let procs = Task::block_on(ProcessList::get().read());
  207. procs
  208. .try_find_process(pid)
  209. .map(|proc| proc.session(procs.prove()).sid)
  210. .ok_or(ESRCH)
  211. }
  212. }
  213. #[eonix_macros::define_syscall(0x84)]
  214. fn getpgid(pid: u32) -> KResult<u32> {
  215. if pid == 0 {
  216. Ok(thread.process.pgroup_rcu().pgid)
  217. } else {
  218. let procs = Task::block_on(ProcessList::get().read());
  219. procs
  220. .try_find_process(pid)
  221. .map(|proc| proc.pgroup(procs.prove()).pgid)
  222. .ok_or(ESRCH)
  223. }
  224. }
  225. #[eonix_macros::define_syscall(0x14)]
  226. fn getpid() -> KResult<u32> {
  227. Ok(thread.process.pid)
  228. }
  229. #[eonix_macros::define_syscall(0x40)]
  230. fn getppid() -> KResult<u32> {
  231. Ok(thread.process.parent_rcu().map_or(0, |x| x.pid))
  232. }
  233. #[eonix_macros::define_syscall(0xc7)]
  234. fn getuid() -> KResult<u32> {
  235. // All users are root for now.
  236. Ok(0)
  237. }
  238. #[eonix_macros::define_syscall(0xca)]
  239. fn geteuid() -> KResult<u32> {
  240. // All users are root for now.
  241. Ok(0)
  242. }
  243. #[eonix_macros::define_syscall(0x2f)]
  244. fn getgid() -> KResult<u32> {
  245. // All users are root for now.
  246. Ok(0)
  247. }
  248. #[eonix_macros::define_syscall(0xc8)]
  249. fn getgid32() -> KResult<u32> {
  250. sys_getgid(thread)
  251. }
  252. #[eonix_macros::define_syscall(0xe0)]
  253. fn gettid() -> KResult<u32> {
  254. Ok(thread.tid)
  255. }
  256. #[eonix_macros::define_syscall(0xf3)]
  257. fn set_thread_area(desc: *mut UserDescriptor) -> KResult<()> {
  258. let desc_pointer = UserPointerMut::new(desc)?;
  259. let mut desc = desc_pointer.read()?;
  260. thread.set_thread_area(&mut desc)?;
  261. desc_pointer.write(desc)?;
  262. // SAFETY: Preemption is disabled on calling `load_thread_area32()`.
  263. unsafe {
  264. eonix_preempt::disable();
  265. thread.load_thread_area32();
  266. eonix_preempt::enable();
  267. }
  268. Ok(())
  269. }
  270. #[eonix_macros::define_syscall(0x102)]
  271. fn set_tid_address(tidptr: *mut u32) -> KResult<u32> {
  272. // TODO!!!: Implement this. We don't use it for now.
  273. let _tidptr = UserPointerMut::new(tidptr)?;
  274. Ok(thread.tid)
  275. }
  276. #[eonix_macros::define_syscall(0xac)]
  277. fn prctl(option: u32, arg2: usize) -> KResult<()> {
  278. match option {
  279. PR_SET_NAME => {
  280. let name = UserPointer::new(arg2 as *mut [u8; 16])?.read()?;
  281. let len = name.iter().position(|&c| c == 0).unwrap_or(15);
  282. thread.set_name(name[..len].into());
  283. Ok(())
  284. }
  285. PR_GET_NAME => {
  286. let name = thread.get_name();
  287. let len = name.len().min(15);
  288. let name: [u8; 16] = core::array::from_fn(|i| if i < len { name[i] } else { 0 });
  289. UserPointerMut::new(arg2 as *mut [u8; 16])?.write(name)?;
  290. Ok(())
  291. }
  292. _ => Err(EINVAL),
  293. }
  294. }
  295. #[eonix_macros::define_syscall(0x25)]
  296. fn kill(pid: i32, sig: u32) -> KResult<()> {
  297. let procs = Task::block_on(ProcessList::get().read());
  298. match pid {
  299. // Send signal to every process for which the calling process has
  300. // permission to send signals.
  301. -1 => unimplemented!("kill with pid -1"),
  302. // Send signal to every process in the process group.
  303. 0 => thread
  304. .process
  305. .pgroup(procs.prove())
  306. .raise(Signal::try_from(sig)?, procs.prove()),
  307. // Send signal to the process with the specified pid.
  308. 1.. => procs
  309. .try_find_process(pid as u32)
  310. .ok_or(ESRCH)?
  311. .raise(Signal::try_from(sig)?, procs.prove()),
  312. // Send signal to the process group with the specified pgid equals to `-pid`.
  313. ..-1 => procs
  314. .try_find_pgroup((-pid) as u32)
  315. .ok_or(ESRCH)?
  316. .raise(Signal::try_from(sig)?, procs.prove()),
  317. }
  318. Ok(())
  319. }
  320. #[eonix_macros::define_syscall(0xee)]
  321. fn tkill(tid: u32, sig: u32) -> KResult<()> {
  322. Task::block_on(ProcessList::get().read())
  323. .try_find_thread(tid)
  324. .ok_or(ESRCH)?
  325. .raise(Signal::try_from(sig)?);
  326. Ok(())
  327. }
  328. #[eonix_macros::define_syscall(0xaf)]
  329. fn rt_sigprocmask(how: u32, set: *mut u64, oldset: *mut u64, sigsetsize: usize) -> KResult<()> {
  330. if sigsetsize != size_of::<u64>() {
  331. return Err(EINVAL);
  332. }
  333. let old_mask = u64::from(thread.signal_list.get_mask());
  334. if !oldset.is_null() {
  335. UserPointerMut::new(oldset)?.write(old_mask)?;
  336. }
  337. let new_mask = if !set.is_null() {
  338. SignalMask::from(UserPointer::new(set)?.read()?)
  339. } else {
  340. return Ok(());
  341. };
  342. match how {
  343. SIG_BLOCK => thread.signal_list.mask(new_mask),
  344. SIG_UNBLOCK => thread.signal_list.unmask(new_mask),
  345. SIG_SETMASK => thread.signal_list.set_mask(new_mask),
  346. _ => return Err(EINVAL),
  347. }
  348. Ok(())
  349. }
  350. #[eonix_macros::define_syscall(0xae)]
  351. fn rt_sigaction(
  352. signum: u32,
  353. act: *const SigAction,
  354. oldact: *mut SigAction,
  355. sigsetsize: usize,
  356. ) -> KResult<()> {
  357. let signal = Signal::try_from(signum)?;
  358. if sigsetsize != size_of::<u64>() {
  359. return Err(EINVAL);
  360. }
  361. // SIGKILL and SIGSTOP MUST not be set for a handler.
  362. if matches!(signal, SIGNAL_NOW!()) {
  363. return Err(EINVAL);
  364. }
  365. let old_action = thread.signal_list.get_action(signal);
  366. if !oldact.is_null() {
  367. UserPointerMut::new(oldact)?.write(old_action.into())?;
  368. }
  369. if !act.is_null() {
  370. let new_action = UserPointer::new(act)?.read()?;
  371. let action: SignalAction = new_action.try_into()?;
  372. thread.signal_list.set_action(signal, action)?;
  373. }
  374. Ok(())
  375. }
  376. #[eonix_macros::define_syscall(0x154)]
  377. fn prlimit64(
  378. pid: u32,
  379. resource: u32,
  380. new_limit: *const RLimit,
  381. old_limit: *mut RLimit,
  382. ) -> KResult<()> {
  383. if pid != 0 {
  384. return Err(ENOSYS);
  385. }
  386. match resource {
  387. RLIMIT_STACK => {
  388. if !old_limit.is_null() {
  389. let old_limit = UserPointerMut::new(old_limit)?;
  390. let rlimit = RLimit {
  391. rlim_cur: 8 * 1024 * 1024,
  392. rlim_max: 8 * 1024 * 1024,
  393. };
  394. old_limit.write(rlimit)?;
  395. }
  396. if !new_limit.is_null() {
  397. return Err(ENOSYS);
  398. }
  399. Ok(())
  400. }
  401. _ => Err(ENOSYS),
  402. }
  403. }
  404. #[eonix_macros::define_syscall(0xbf)]
  405. fn getrlimit(resource: u32, rlimit: *mut RLimit) -> KResult<()> {
  406. sys_prlimit64(thread, 0, resource, core::ptr::null(), rlimit)
  407. }
  408. #[repr(C)]
  409. #[derive(Clone, Copy)]
  410. struct RUsage {
  411. ru_utime: TimeVal,
  412. ru_stime: TimeVal,
  413. ru_maxrss: u32,
  414. ru_ixrss: u32,
  415. ru_idrss: u32,
  416. ru_isrss: u32,
  417. ru_minflt: u32,
  418. ru_majflt: u32,
  419. ru_nswap: u32,
  420. ru_inblock: u32,
  421. ru_oublock: u32,
  422. ru_msgsnd: u32,
  423. ru_msgrcv: u32,
  424. ru_nsignals: u32,
  425. ru_nvcsw: u32,
  426. ru_nivcsw: u32,
  427. }
  428. #[eonix_macros::define_syscall(0x4d)]
  429. fn getrusage(who: u32, rusage: *mut RUsage) -> KResult<()> {
  430. if who != 0 {
  431. return Err(ENOSYS);
  432. }
  433. let rusage = UserPointerMut::new(rusage)?;
  434. rusage.write(RUsage {
  435. ru_utime: TimeVal::default(),
  436. ru_stime: TimeVal::default(),
  437. ru_maxrss: 0,
  438. ru_ixrss: 0,
  439. ru_idrss: 0,
  440. ru_isrss: 0,
  441. ru_minflt: 0,
  442. ru_majflt: 0,
  443. ru_nswap: 0,
  444. ru_inblock: 0,
  445. ru_oublock: 0,
  446. ru_msgsnd: 0,
  447. ru_msgrcv: 0,
  448. ru_nsignals: 0,
  449. ru_nvcsw: 0,
  450. ru_nivcsw: 0,
  451. })?;
  452. Ok(())
  453. }
  454. #[eonix_macros::define_syscall(0x0f)]
  455. fn chmod(pathname: *const u8, mode: u32) -> KResult<()> {
  456. let path = UserString::new(pathname)?;
  457. let path = Path::new(path.as_cstr().to_bytes())?;
  458. let dentry = Dentry::open(&thread.fs_context, path, true)?;
  459. if !dentry.is_valid() {
  460. return Err(ENOENT);
  461. }
  462. dentry.chmod(mode)
  463. }
  464. #[eonix_macros::define_syscall(0xbe)]
  465. fn vfork() -> u32 {
  466. sys_fork(thread)
  467. }
  468. #[eonix_macros::define_syscall(0x02)]
  469. fn fork() -> u32 {
  470. let mut procs = Task::block_on(ProcessList::get().write());
  471. let current_process = thread.process.clone();
  472. let current_pgroup = current_process.pgroup(procs.prove()).clone();
  473. let current_session = current_process.session(procs.prove()).clone();
  474. let thread_builder = ThreadBuilder::new().fork_from(&thread);
  475. let (new_thread, new_process) = ProcessBuilder::new()
  476. .mm_list(Task::block_on(current_process.mm_list.new_cloned()))
  477. .parent(current_process)
  478. .pgroup(current_pgroup)
  479. .session(current_session)
  480. .thread_builder(thread_builder)
  481. .build(&mut procs);
  482. Scheduler::get().spawn::<KernelStack, _>(ThreadRunnable::new(new_thread));
  483. new_process.pid
  484. }
  485. #[eonix_macros::define_syscall(0x77)]
  486. fn sigreturn() -> KResult<SyscallNoReturn> {
  487. thread
  488. .signal_list
  489. .restore(
  490. &mut thread.trap_ctx.borrow(),
  491. &mut thread.fpu_state.borrow(),
  492. )
  493. .inspect_err(|err| {
  494. println_warn!(
  495. "`sigreturn` failed in thread {} with error {err}!",
  496. thread.tid
  497. );
  498. thread.raise(Signal::SIGSEGV);
  499. })?;
  500. Ok(SyscallNoReturn)
  501. }
  502. // TODO: This should be for x86 only.
  503. #[eonix_macros::define_syscall(0x180)]
  504. fn arch_prctl(option: u32, addr: u32) -> KResult<u32> {
  505. sys_arch_prctl(thread, option, addr)
  506. }