procops.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. use alloc::borrow::ToOwned;
  2. use alloc::ffi::CString;
  3. use arch::{ExtendedContext, InterruptContext};
  4. use bindings::{EINVAL, ENOENT, ENOTDIR, ERANGE, ESRCH};
  5. use bitflags::bitflags;
  6. use crate::elf::ParsedElf32;
  7. use crate::io::Buffer;
  8. use crate::kernel::constants::{
  9. ENOSYS, PR_GET_NAME, PR_SET_NAME, RLIMIT_STACK, SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK,
  10. };
  11. use crate::kernel::mem::{Page, PageBuffer, VAddr};
  12. use crate::kernel::task::{
  13. ProcessList, Scheduler, Signal, SignalAction, Thread, UserDescriptor, WaitObject, WaitType,
  14. };
  15. use crate::kernel::user::dataflow::UserString;
  16. use crate::kernel::user::{UserPointer, UserPointerMut};
  17. use crate::kernel::vfs::dentry::Dentry;
  18. use crate::path::Path;
  19. use crate::sync::{preempt, AsRefPosition as _};
  20. use crate::{kernel::user::dataflow::UserBuffer, prelude::*};
  21. use crate::kernel::vfs::{self, FsContext};
  22. use super::{define_syscall32, register_syscall};
  23. fn do_umask(mask: u32) -> KResult<u32> {
  24. let context = FsContext::get_current();
  25. let mut umask = context.umask.lock();
  26. let old = *umask;
  27. *umask = mask & 0o777;
  28. Ok(old)
  29. }
  30. fn do_getcwd(buffer: *mut u8, bufsize: usize) -> KResult<usize> {
  31. let context = FsContext::get_current();
  32. let mut user_buffer = UserBuffer::new(buffer, bufsize)?;
  33. let page = Page::alloc_one();
  34. let mut buffer = PageBuffer::new(page.clone());
  35. context.cwd.lock().get_path(&context, &mut buffer)?;
  36. user_buffer.fill(page.as_slice())?.ok_or(ERANGE)?;
  37. Ok(buffer.wrote())
  38. }
  39. fn do_chdir(path: *const u8) -> KResult<()> {
  40. let context = FsContext::get_current();
  41. let path = UserString::new(path)?;
  42. let path = Path::new(path.as_cstr().to_bytes())?;
  43. let dentry = Dentry::open(&context, path, true)?;
  44. if !dentry.is_valid() {
  45. return Err(ENOENT);
  46. }
  47. if !dentry.is_directory() {
  48. return Err(ENOTDIR);
  49. }
  50. *context.cwd.lock() = dentry;
  51. Ok(())
  52. }
  53. fn do_mount(source: *const u8, target: *const u8, fstype: *const u8, flags: usize) -> KResult<()> {
  54. let source = UserString::new(source)?;
  55. let target = UserString::new(target)?;
  56. let fstype = UserString::new(fstype)?;
  57. let context = FsContext::get_current();
  58. let mountpoint = Dentry::open(&context, Path::new(target.as_cstr().to_bytes())?, true)?;
  59. if !mountpoint.is_valid() {
  60. return Err(ENOENT);
  61. }
  62. vfs::mount::do_mount(
  63. &mountpoint,
  64. source.as_cstr().to_str().map_err(|_| EINVAL)?,
  65. target.as_cstr().to_str().map_err(|_| EINVAL)?,
  66. fstype.as_cstr().to_str().map_err(|_| EINVAL)?,
  67. flags as u64,
  68. )
  69. }
  70. /// # Return
  71. /// `(entry_ip, sp)`
  72. fn do_execve(exec: &[u8], argv: Vec<CString>, envp: Vec<CString>) -> KResult<(VAddr, VAddr)> {
  73. let dentry = Dentry::open(&FsContext::get_current(), Path::new(exec)?, true)?;
  74. if !dentry.is_valid() {
  75. return Err(ENOENT);
  76. }
  77. // TODO: When `execve` is called by one of the threads in a process, the other threads
  78. // should be terminated and `execve` is performed in the thread group leader.
  79. let elf = ParsedElf32::parse(dentry.clone())?;
  80. let result = elf.load(&Thread::current().process.mm_list, argv, envp);
  81. if let Ok((ip, sp)) = result {
  82. Thread::current().files.on_exec();
  83. Thread::current().signal_list.clear_non_ignore();
  84. Thread::current().set_name(dentry.name().clone());
  85. Ok((ip, sp))
  86. } else {
  87. drop(dentry);
  88. // We can't hold any ownership when we call `kill_current`.
  89. ProcessList::kill_current(Signal::SIGSEGV);
  90. }
  91. }
  92. fn sys_execve(int_stack: &mut InterruptContext, _: &mut ExtendedContext) -> usize {
  93. match (|| -> KResult<()> {
  94. let exec = int_stack.rbx as *const u8;
  95. let exec = UserString::new(exec)?;
  96. // TODO!!!!!: copy from user
  97. let mut argv = UserPointer::<u32>::new_vaddr(int_stack.rcx as _)?;
  98. let mut envp = UserPointer::<u32>::new_vaddr(int_stack.rdx as _)?;
  99. let mut argv_vec = Vec::new();
  100. let mut envp_vec = Vec::new();
  101. loop {
  102. let arg = argv.read()?;
  103. if arg == 0 {
  104. break;
  105. }
  106. let arg = UserString::new(arg as *const u8)?;
  107. argv_vec.push(arg.as_cstr().to_owned());
  108. argv = argv.offset(1)?;
  109. }
  110. loop {
  111. let arg = envp.read()?;
  112. if arg == 0 {
  113. break;
  114. }
  115. let arg = UserString::new(arg as *const u8)?;
  116. envp_vec.push(arg.as_cstr().to_owned());
  117. envp = envp.offset(1)?;
  118. }
  119. let (ip, sp) = do_execve(exec.as_cstr().to_bytes(), argv_vec, envp_vec)?;
  120. int_stack.rip = ip.0 as u64;
  121. int_stack.rsp = sp.0 as u64;
  122. Ok(())
  123. })() {
  124. Ok(_) => 0,
  125. Err(err) => -(err as i32) as _,
  126. }
  127. }
  128. // TODO: Find a better way.
  129. #[allow(unreachable_code)]
  130. fn do_exit(status: u32) -> KResult<()> {
  131. {
  132. let mut procs = ProcessList::get().lock();
  133. procs.do_kill_process(&Thread::current().process, WaitType::Exited(status));
  134. }
  135. Scheduler::schedule_noreturn();
  136. panic!("schedule_noreturn returned!");
  137. }
  138. bitflags! {
  139. pub struct UserWaitOptions: u32 {
  140. const WNOHANG = 1;
  141. const WUNTRACED = 2;
  142. const WCONTINUED = 8;
  143. }
  144. }
  145. fn do_waitpid(waitpid: u32, arg1: *mut u32, options: u32) -> KResult<u32> {
  146. if waitpid != u32::MAX {
  147. unimplemented!("waitpid with pid {waitpid}")
  148. }
  149. let options = match UserWaitOptions::from_bits(options) {
  150. None => unimplemented!("waitpid with options {options}"),
  151. Some(options) => options,
  152. };
  153. let wait_object = Thread::current().process.wait(
  154. options.contains(UserWaitOptions::WNOHANG),
  155. options.contains(UserWaitOptions::WUNTRACED),
  156. options.contains(UserWaitOptions::WCONTINUED),
  157. )?;
  158. match wait_object {
  159. None => Ok(0),
  160. Some(WaitObject { pid, code }) => {
  161. if !arg1.is_null() {
  162. UserPointerMut::new(arg1)?.write(code.to_wstatus())?;
  163. }
  164. Ok(pid)
  165. }
  166. }
  167. }
  168. fn do_wait4(waitpid: u32, arg1: *mut u32, options: u32, rusage: *mut ()) -> KResult<u32> {
  169. if rusage.is_null() {
  170. do_waitpid(waitpid, arg1, options)
  171. } else {
  172. unimplemented!("wait4 with rusage")
  173. }
  174. }
  175. fn do_setsid() -> KResult<u32> {
  176. Thread::current().process.setsid()
  177. }
  178. fn do_setpgid(pid: u32, pgid: i32) -> KResult<()> {
  179. let pid = if pid == 0 { Thread::current().process.pid } else { pid };
  180. let pgid = match pgid {
  181. 0 => pid,
  182. 1.. => pgid as u32,
  183. _ => return Err(EINVAL),
  184. };
  185. Thread::current().process.setpgid(pid, pgid)
  186. }
  187. fn do_getsid(pid: u32) -> KResult<u32> {
  188. if pid == 0 {
  189. Ok(Thread::current().process.session_rcu().sid)
  190. } else {
  191. let procs = ProcessList::get().lock_shared();
  192. procs
  193. .try_find_process(pid)
  194. .map(|proc| proc.session(procs.as_pos()).sid)
  195. .ok_or(ESRCH)
  196. }
  197. }
  198. fn do_getpgid(pid: u32) -> KResult<u32> {
  199. if pid == 0 {
  200. Ok(Thread::current().process.pgroup_rcu().pgid)
  201. } else {
  202. let procs = ProcessList::get().lock_shared();
  203. procs
  204. .try_find_process(pid)
  205. .map(|proc| proc.pgroup(procs.as_pos()).pgid)
  206. .ok_or(ESRCH)
  207. }
  208. }
  209. fn do_getpid() -> KResult<u32> {
  210. Ok(Thread::current().process.pid)
  211. }
  212. fn do_getppid() -> KResult<u32> {
  213. Ok(Thread::current().process.parent_rcu().map_or(0, |x| x.pid))
  214. }
  215. fn do_getuid() -> KResult<u32> {
  216. // All users are root for now.
  217. Ok(0)
  218. }
  219. fn do_geteuid() -> KResult<u32> {
  220. // All users are root for now.
  221. Ok(0)
  222. }
  223. fn do_getgid() -> KResult<u32> {
  224. // All users are root for now.
  225. Ok(0)
  226. }
  227. fn do_gettid() -> KResult<u32> {
  228. Ok(Thread::current().tid)
  229. }
  230. fn do_set_thread_area(desc: *mut UserDescriptor) -> KResult<()> {
  231. let desc_pointer = UserPointerMut::new(desc)?;
  232. let mut desc = desc_pointer.read()?;
  233. Thread::current().set_thread_area(&mut desc)?;
  234. desc_pointer.write(desc)?;
  235. // SAFETY: Preemption is disabled on calling `load_thread_area32()`.
  236. unsafe {
  237. preempt::disable();
  238. Thread::current().load_thread_area32();
  239. preempt::enable();
  240. }
  241. Ok(())
  242. }
  243. fn do_set_tid_address(tidptr: *mut u32) -> KResult<u32> {
  244. // TODO!!!: Implement this. We don't use it for now.
  245. let _tidptr = UserPointerMut::new(tidptr)?;
  246. Ok(Thread::current().tid)
  247. }
  248. fn do_prctl(option: u32, arg2: usize) -> KResult<()> {
  249. match option {
  250. PR_SET_NAME => {
  251. let name = UserPointer::new(arg2 as *mut [u8; 16])?.read()?;
  252. let len = name.iter().position(|&c| c == 0).unwrap_or(15);
  253. Thread::current().set_name(name[..len].into());
  254. Ok(())
  255. }
  256. PR_GET_NAME => {
  257. let name = Thread::current().get_name();
  258. let len = name.len().min(15);
  259. let name: [u8; 16] = core::array::from_fn(|i| if i < len { name[i] } else { 0 });
  260. UserPointerMut::new(arg2 as *mut [u8; 16])?.write(name)?;
  261. Ok(())
  262. }
  263. _ => Err(EINVAL),
  264. }
  265. }
  266. fn do_kill(pid: i32, sig: u32) -> KResult<()> {
  267. let procs = ProcessList::get().lock_shared();
  268. match pid {
  269. // Send signal to every process for which the calling process has
  270. // permission to send signals.
  271. -1 => unimplemented!("kill with pid -1"),
  272. // Send signal to every process in the process group.
  273. 0 => Thread::current()
  274. .process
  275. .pgroup(procs.as_pos())
  276. .raise(Signal::try_from(sig)?, procs.as_pos()),
  277. // Send signal to the process with the specified pid.
  278. 1.. => procs
  279. .try_find_process(pid as u32)
  280. .ok_or(ESRCH)?
  281. .raise(Signal::try_from(sig)?, procs.as_pos()),
  282. // Send signal to the process group with the specified pgid equals to `-pid`.
  283. ..-1 => procs
  284. .try_find_pgroup((-pid) as u32)
  285. .ok_or(ESRCH)?
  286. .raise(Signal::try_from(sig)?, procs.as_pos()),
  287. }
  288. Ok(())
  289. }
  290. fn do_tkill(tid: u32, sig: u32) -> KResult<()> {
  291. ProcessList::get()
  292. .lock_shared()
  293. .try_find_thread(tid)
  294. .ok_or(ESRCH)?
  295. .raise(Signal::try_from(sig)?);
  296. Ok(())
  297. }
  298. fn do_rt_sigprocmask(how: u32, set: *mut u64, oldset: *mut u64, sigsetsize: usize) -> KResult<()> {
  299. if sigsetsize != size_of::<u64>() {
  300. return Err(EINVAL);
  301. }
  302. let old_mask = Thread::current().signal_list.get_mask();
  303. if !oldset.is_null() {
  304. UserPointerMut::new(oldset)?.write(old_mask)?;
  305. }
  306. let new_mask = if !set.is_null() {
  307. UserPointer::new(set)?.read()?
  308. } else {
  309. return Ok(());
  310. };
  311. match how {
  312. SIG_BLOCK => Thread::current().signal_list.mask(new_mask),
  313. SIG_UNBLOCK => Thread::current().signal_list.unmask(new_mask),
  314. SIG_SETMASK => Thread::current().signal_list.set_mask(new_mask),
  315. _ => return Err(EINVAL),
  316. }
  317. Ok(())
  318. }
  319. #[repr(C, packed)]
  320. #[derive(Debug, Clone, Copy)]
  321. struct UserSignalAction {
  322. sa_handler: u32,
  323. sa_flags: u32,
  324. sa_restorer: u32,
  325. sa_mask: u64,
  326. }
  327. impl From<UserSignalAction> for SignalAction {
  328. fn from(from: UserSignalAction) -> SignalAction {
  329. SignalAction {
  330. sa_handler: from.sa_handler as usize,
  331. sa_flags: from.sa_flags as usize,
  332. sa_mask: from.sa_mask as usize,
  333. sa_restorer: from.sa_restorer as usize,
  334. }
  335. }
  336. }
  337. impl From<SignalAction> for UserSignalAction {
  338. fn from(from: SignalAction) -> UserSignalAction {
  339. UserSignalAction {
  340. sa_handler: from.sa_handler as u32,
  341. sa_flags: from.sa_flags as u32,
  342. sa_mask: from.sa_mask as u64,
  343. sa_restorer: from.sa_restorer as u32,
  344. }
  345. }
  346. }
  347. fn do_rt_sigaction(
  348. signum: u32,
  349. act: *const UserSignalAction,
  350. oldact: *mut UserSignalAction,
  351. sigsetsize: usize,
  352. ) -> KResult<()> {
  353. let signal = Signal::try_from(signum)?;
  354. if sigsetsize != size_of::<u64>() || signal.is_now() {
  355. return Err(EINVAL);
  356. }
  357. let old_action = Thread::current().signal_list.get_handler(signal);
  358. if !oldact.is_null() {
  359. UserPointerMut::new(oldact)?.write(old_action.into())?;
  360. }
  361. if !act.is_null() {
  362. let new_action = UserPointer::new(act)?.read()?;
  363. Thread::current()
  364. .signal_list
  365. .set_handler(signal, &new_action.into())?;
  366. }
  367. Ok(())
  368. }
  369. #[repr(C)]
  370. #[derive(Debug, Clone, Copy)]
  371. struct RLimit {
  372. rlim_cur: u64,
  373. rlim_max: u64,
  374. }
  375. fn do_prlimit64(
  376. pid: u32,
  377. resource: u32,
  378. new_limit: *const RLimit,
  379. old_limit: *mut RLimit,
  380. ) -> KResult<()> {
  381. println_debug!(
  382. "prlimit64({}, {}, {:?}, {:?})",
  383. pid,
  384. resource,
  385. new_limit,
  386. old_limit
  387. );
  388. if pid != 0 {
  389. return Err(ENOSYS);
  390. }
  391. match resource {
  392. RLIMIT_STACK => {
  393. if !old_limit.is_null() {
  394. let old_limit = UserPointerMut::new(old_limit)?;
  395. let rlimit = RLimit {
  396. rlim_cur: 8 * 1024 * 1024,
  397. rlim_max: 8 * 1024 * 1024,
  398. };
  399. old_limit.write(rlimit)?;
  400. }
  401. if !new_limit.is_null() {
  402. return Err(ENOSYS);
  403. }
  404. Ok(())
  405. }
  406. _ => Err(ENOSYS),
  407. }
  408. }
  409. define_syscall32!(sys_chdir, do_chdir, path: *const u8);
  410. define_syscall32!(sys_umask, do_umask, mask: u32);
  411. define_syscall32!(sys_getcwd, do_getcwd, buffer: *mut u8, bufsize: usize);
  412. define_syscall32!(sys_exit, do_exit, status: u32);
  413. define_syscall32!(sys_waitpid, do_waitpid, waitpid: u32, arg1: *mut u32, options: u32);
  414. define_syscall32!(sys_wait4, do_wait4, waitpid: u32, arg1: *mut u32, options: u32, rusage: *mut ());
  415. define_syscall32!(sys_setsid, do_setsid);
  416. define_syscall32!(sys_setpgid, do_setpgid, pid: u32, pgid: i32);
  417. define_syscall32!(sys_getsid, do_getsid, pid: u32);
  418. define_syscall32!(sys_getpgid, do_getpgid, pid: u32);
  419. define_syscall32!(sys_getpid, do_getpid);
  420. define_syscall32!(sys_getppid, do_getppid);
  421. define_syscall32!(sys_getuid, do_getuid);
  422. define_syscall32!(sys_geteuid, do_geteuid);
  423. define_syscall32!(sys_getgid, do_getgid);
  424. define_syscall32!(sys_gettid, do_gettid);
  425. define_syscall32!(sys_mount, do_mount,
  426. source: *const u8, target: *const u8,fstype: *const u8, flags: usize);
  427. define_syscall32!(sys_set_thread_area, do_set_thread_area, desc: *mut UserDescriptor);
  428. define_syscall32!(sys_set_tid_address, do_set_tid_address, tidptr: *mut u32);
  429. define_syscall32!(sys_prctl, do_prctl, option: u32, arg2: usize);
  430. define_syscall32!(sys_arch_prctl, do_prctl, option: u32, arg2: usize);
  431. define_syscall32!(sys_kill, do_kill, pid: i32, sig: u32);
  432. define_syscall32!(sys_tkill, do_tkill, tid: u32, sig: u32);
  433. define_syscall32!(sys_rt_sigprocmask, do_rt_sigprocmask,
  434. how: u32, set: *mut u64, oldset: *mut u64, sigsetsize: usize);
  435. define_syscall32!(sys_rt_sigaction, do_rt_sigaction,
  436. signum: u32, act: *const UserSignalAction, oldact: *mut UserSignalAction, sigsetsize: usize);
  437. define_syscall32!(sys_prlimit64, do_prlimit64,
  438. pid: u32, resource: u32, new_limit: *const RLimit, old_limit: *mut RLimit);
  439. fn sys_fork(int_stack: &mut InterruptContext, _: &mut ExtendedContext) -> usize {
  440. let mut procs = ProcessList::get().lock();
  441. let new_thread = Thread::current().new_cloned(procs.as_mut());
  442. let mut new_int_stack = int_stack.clone();
  443. new_int_stack.rax = 0;
  444. new_int_stack.eflags = 0x200;
  445. new_thread.fork_init(new_int_stack);
  446. Scheduler::get().lock_irq().uwake(&new_thread);
  447. new_thread.process.pid as usize
  448. }
  449. fn sys_sigreturn(int_stack: &mut InterruptContext, ext_ctx: &mut ExtendedContext) -> usize {
  450. let result = Thread::current().signal_list.restore(int_stack, ext_ctx);
  451. match result {
  452. Ok(ret) => ret,
  453. Err(_) => {
  454. println_warn!("`sigreturn` failed in thread {}!", Thread::current().tid);
  455. Thread::current().raise(Signal::SIGSEGV);
  456. 0
  457. }
  458. }
  459. }
  460. pub(super) fn register() {
  461. register_syscall!(0x01, exit);
  462. register_syscall!(0x02, fork);
  463. register_syscall!(0x07, waitpid);
  464. register_syscall!(0x0b, execve);
  465. register_syscall!(0x0c, chdir);
  466. register_syscall!(0x14, getpid);
  467. register_syscall!(0x15, mount);
  468. register_syscall!(0x25, kill);
  469. register_syscall!(0x2f, getgid);
  470. register_syscall!(0x39, setpgid);
  471. register_syscall!(0x3c, umask);
  472. register_syscall!(0x40, getppid);
  473. register_syscall!(0x42, setsid);
  474. register_syscall!(0x72, wait4);
  475. register_syscall!(0x77, sigreturn);
  476. register_syscall!(0x84, getpgid);
  477. register_syscall!(0x93, getsid);
  478. register_syscall!(0xac, prctl);
  479. register_syscall!(0xae, rt_sigaction);
  480. register_syscall!(0xaf, rt_sigprocmask);
  481. register_syscall!(0xb7, getcwd);
  482. register_syscall!(0xc7, getuid);
  483. register_syscall!(0xc8, getgid);
  484. register_syscall!(0xc9, geteuid);
  485. register_syscall!(0xca, geteuid);
  486. register_syscall!(0xe0, gettid);
  487. register_syscall!(0xee, tkill);
  488. register_syscall!(0xf3, set_thread_area);
  489. register_syscall!(0xfc, exit);
  490. register_syscall!(0x102, set_tid_address);
  491. register_syscall!(0x154, prlimit64);
  492. register_syscall!(0x180, arch_prctl);
  493. }