signal.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. use core::{cmp::Reverse, task::Waker};
  2. use crate::{
  3. io::BufferFill,
  4. kernel::{
  5. constants::{SA_RESTORER, SA_SIGINFO},
  6. user::{dataflow::UserBuffer, UserPointer},
  7. },
  8. prelude::*,
  9. sync::{preempt, AsRefPosition as _},
  10. };
  11. use alloc::collections::{binary_heap::BinaryHeap, btree_map::BTreeMap};
  12. use arch::{ExtendedContext, InterruptContext};
  13. use bindings::{EFAULT, EINVAL};
  14. use super::{ProcessList, Scheduler, Task, Thread, WaitObject, WaitType};
  15. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
  16. pub struct Signal(u32);
  17. #[allow(dead_code)]
  18. impl Signal {
  19. pub const SIGHUP: Signal = Signal(1);
  20. pub const SIGINT: Signal = Signal(2);
  21. pub const SIGQUIT: Signal = Signal(3);
  22. pub const SIGILL: Signal = Signal(4);
  23. pub const SIGTRAP: Signal = Signal(5);
  24. pub const SIGABRT: Signal = Signal(6);
  25. pub const SIGIOT: Signal = Signal(6);
  26. pub const SIGBUS: Signal = Signal(7);
  27. pub const SIGFPE: Signal = Signal(8);
  28. pub const SIGKILL: Signal = Signal(9);
  29. pub const SIGUSR1: Signal = Signal(10);
  30. pub const SIGSEGV: Signal = Signal(11);
  31. pub const SIGUSR2: Signal = Signal(12);
  32. pub const SIGPIPE: Signal = Signal(13);
  33. pub const SIGALRM: Signal = Signal(14);
  34. pub const SIGTERM: Signal = Signal(15);
  35. pub const SIGSTKFLT: Signal = Signal(16);
  36. pub const SIGCHLD: Signal = Signal(17);
  37. pub const SIGCONT: Signal = Signal(18);
  38. pub const SIGSTOP: Signal = Signal(19);
  39. pub const SIGTSTP: Signal = Signal(20);
  40. pub const SIGTTIN: Signal = Signal(21);
  41. pub const SIGTTOU: Signal = Signal(22);
  42. pub const SIGURG: Signal = Signal(23);
  43. pub const SIGXCPU: Signal = Signal(24);
  44. pub const SIGXFSZ: Signal = Signal(25);
  45. pub const SIGVTALRM: Signal = Signal(26);
  46. pub const SIGPROF: Signal = Signal(27);
  47. pub const SIGWINCH: Signal = Signal(28);
  48. pub const SIGIO: Signal = Signal(29);
  49. pub const SIGPOLL: Signal = Signal(29);
  50. pub const SIGPWR: Signal = Signal(30);
  51. pub const SIGSYS: Signal = Signal(31);
  52. }
  53. #[derive(Debug, Clone, Copy)]
  54. pub struct SignalAction {
  55. pub sa_handler: usize,
  56. pub sa_flags: usize,
  57. pub sa_restorer: usize,
  58. pub sa_mask: usize,
  59. }
  60. #[derive(Debug)]
  61. struct SignalListInner {
  62. mask: u64,
  63. pending: BinaryHeap<Reverse<Signal>>,
  64. signal_waker: Option<Waker>,
  65. stop_waker: Option<Waker>,
  66. // TODO!!!!!: Signal disposition should be per-process.
  67. handlers: BTreeMap<Signal, SignalAction>,
  68. }
  69. #[derive(Debug)]
  70. pub struct SignalList {
  71. /// We might use this inside interrupt handler, so we need to use `lock_irq`.
  72. inner: Spin<SignalListInner>,
  73. }
  74. impl Clone for SignalList {
  75. fn clone(&self) -> Self {
  76. let inner = self.inner.lock();
  77. debug_assert!(
  78. inner.stop_waker.is_none(),
  79. "We should not have a stop waker here"
  80. );
  81. Self {
  82. inner: Spin::new(SignalListInner {
  83. mask: inner.mask,
  84. pending: BinaryHeap::new(),
  85. signal_waker: None,
  86. stop_waker: None,
  87. handlers: inner.handlers.clone(),
  88. }),
  89. }
  90. }
  91. }
  92. #[derive(Debug, Clone, Copy)]
  93. pub enum RaiseResult {
  94. Finished,
  95. Masked,
  96. }
  97. impl Signal {
  98. const fn is_ignore(&self) -> bool {
  99. match *self {
  100. Self::SIGCHLD | Self::SIGURG | Self::SIGWINCH => true,
  101. _ => false,
  102. }
  103. }
  104. pub const fn is_now(&self) -> bool {
  105. match *self {
  106. Self::SIGKILL | Self::SIGSTOP => true,
  107. _ => false,
  108. }
  109. }
  110. pub const fn is_coredump(&self) -> bool {
  111. match *self {
  112. Self::SIGQUIT
  113. | Self::SIGILL
  114. | Self::SIGABRT
  115. | Self::SIGFPE
  116. | Self::SIGSEGV
  117. | Self::SIGBUS
  118. | Self::SIGTRAP
  119. | Self::SIGSYS
  120. | Self::SIGXCPU
  121. | Self::SIGXFSZ => true,
  122. _ => false,
  123. }
  124. }
  125. fn to_mask(&self) -> u64 {
  126. 1 << (self.0 - 1)
  127. }
  128. }
  129. impl TryFrom<u32> for Signal {
  130. type Error = u32;
  131. fn try_from(signum: u32) -> Result<Self, Self::Error> {
  132. if signum > 0 && signum <= 64 {
  133. Ok(Self(signum))
  134. } else {
  135. Err(EINVAL)
  136. }
  137. }
  138. }
  139. impl From<Signal> for u32 {
  140. fn from(signal: Signal) -> Self {
  141. let Signal(signum) = signal;
  142. signum
  143. }
  144. }
  145. impl SignalAction {
  146. fn default_action() -> Self {
  147. Self {
  148. sa_handler: 0,
  149. sa_flags: 0,
  150. sa_restorer: 0,
  151. sa_mask: 0,
  152. }
  153. }
  154. fn is_ignore(&self) -> bool {
  155. const SIG_IGN: usize = 1;
  156. self.sa_handler == SIG_IGN
  157. }
  158. fn is_default(&self) -> bool {
  159. const SIG_DFL: usize = 0;
  160. self.sa_handler == SIG_DFL
  161. }
  162. /// # Might Sleep
  163. fn handle(
  164. &self,
  165. signal: Signal,
  166. old_mask: u64,
  167. int_stack: &mut InterruptContext,
  168. ext_ctx: &mut ExtendedContext,
  169. ) -> KResult<()> {
  170. if self.sa_flags & SA_RESTORER as usize == 0 {
  171. return Err(EINVAL);
  172. }
  173. const CONTEXT_SIZE: usize = size_of::<InterruptContext>()
  174. + size_of::<ExtendedContext>()
  175. + size_of::<usize>() // old_mask
  176. + size_of::<u32>(); // `sa_handler` argument: `signum`
  177. // Save current interrupt context to 128 bytes above current user stack
  178. // and align to 16 bytes. Then we push the return address of the restorer.
  179. // TODO!!!: Determine the size of the return address
  180. let sp = ((int_stack.rsp as usize - 128 - CONTEXT_SIZE) & !0xf) - size_of::<u32>();
  181. let restorer_address: u32 = self.sa_restorer as u32;
  182. let mut stack = UserBuffer::new(sp as *mut u8, CONTEXT_SIZE + size_of::<u32>())?;
  183. stack.copy(&restorer_address)?.ok_or(EFAULT)?; // Restorer address
  184. stack.copy(&u32::from(signal))?.ok_or(EFAULT)?; // Restorer address
  185. stack.copy(&old_mask)?.ok_or(EFAULT)?; // Original signal mask
  186. stack.copy(ext_ctx)?.ok_or(EFAULT)?; // MMX registers
  187. stack.copy(int_stack)?.ok_or(EFAULT)?; // Interrupt stack
  188. int_stack.rip = self.sa_handler as u64;
  189. int_stack.rsp = sp as u64;
  190. Ok(())
  191. }
  192. }
  193. impl SignalListInner {
  194. fn get_mask(&self) -> u64 {
  195. self.mask
  196. }
  197. fn set_mask(&mut self, mask: u64) {
  198. self.mask = mask;
  199. }
  200. fn mask(&mut self, mask: u64) {
  201. self.set_mask(self.mask | mask)
  202. }
  203. fn unmask(&mut self, mask: u64) {
  204. self.set_mask(self.mask & !mask)
  205. }
  206. fn is_masked(&self, signal: Signal) -> bool {
  207. self.mask & signal.to_mask() != 0
  208. }
  209. fn pop(&mut self) -> Option<Signal> {
  210. self.pending.pop().map(|Reverse(signal)| signal)
  211. }
  212. fn raise(&mut self, signal: Signal) -> RaiseResult {
  213. if self.is_masked(signal) {
  214. return RaiseResult::Masked;
  215. }
  216. match self.handlers.get(&signal) {
  217. // Ignore action
  218. Some(handler) if handler.is_ignore() => return RaiseResult::Finished,
  219. // Default action
  220. None if signal.is_ignore() => return RaiseResult::Finished,
  221. _ => {}
  222. }
  223. self.mask(signal.to_mask());
  224. self.pending.push(Reverse(signal));
  225. match signal {
  226. Signal::SIGCONT => {
  227. self.stop_waker.take().map(|waker| waker.wake());
  228. }
  229. _ => {
  230. let waker = self
  231. .signal_waker
  232. .as_ref()
  233. .expect("We should have a signal waker");
  234. waker.wake_by_ref();
  235. }
  236. }
  237. return RaiseResult::Finished;
  238. }
  239. }
  240. impl SignalList {
  241. pub fn new() -> Self {
  242. Self {
  243. inner: Spin::new(SignalListInner {
  244. mask: 0,
  245. pending: BinaryHeap::new(),
  246. signal_waker: None,
  247. stop_waker: None,
  248. handlers: BTreeMap::new(),
  249. }),
  250. }
  251. }
  252. pub fn get_mask(&self) -> u64 {
  253. self.inner.lock_irq().get_mask()
  254. }
  255. pub fn set_mask(&self, mask: u64) {
  256. self.inner.lock_irq().set_mask(mask)
  257. }
  258. pub fn mask(&self, mask: u64) {
  259. self.inner.lock_irq().set_mask(mask)
  260. }
  261. pub fn unmask(&self, mask: u64) {
  262. self.inner.lock_irq().unmask(mask)
  263. }
  264. pub fn set_handler(&self, signal: Signal, action: &SignalAction) -> KResult<()> {
  265. if signal.is_now() || action.sa_flags & SA_SIGINFO as usize != 0 {
  266. return Err(EINVAL);
  267. }
  268. let mut inner = self.inner.lock_irq();
  269. if action.is_default() {
  270. inner.handlers.remove(&signal);
  271. } else {
  272. inner.handlers.insert(signal, action.clone());
  273. }
  274. Ok(())
  275. }
  276. pub fn get_handler(&self, signal: Signal) -> SignalAction {
  277. self.inner
  278. .lock_irq()
  279. .handlers
  280. .get(&signal)
  281. .cloned()
  282. .unwrap_or_else(SignalAction::default_action)
  283. }
  284. // TODO!!!: Find a better way.
  285. pub fn set_signal_waker(&self, waker: Waker) {
  286. let mut inner = self.inner.lock_irq();
  287. let old_waker = inner.signal_waker.replace(waker);
  288. assert!(old_waker.is_none(), "We should not have a waker here");
  289. }
  290. /// Clear all signals except for `SIG_IGN`.
  291. /// This is used when `execve` is called.
  292. pub fn clear_non_ignore(&self) {
  293. self.inner
  294. .lock_irq()
  295. .handlers
  296. .retain(|_, action| action.is_ignore());
  297. }
  298. /// Clear all pending signals.
  299. /// This is used when `fork` is called.
  300. pub fn clear_pending(&self) {
  301. self.inner.lock_irq().pending.clear()
  302. }
  303. pub fn has_pending_signal(&self) -> bool {
  304. !self.inner.lock_irq().pending.is_empty()
  305. }
  306. /// Do not use this, use `Thread::raise` instead.
  307. pub(super) fn raise(&self, signal: Signal) -> RaiseResult {
  308. self.inner.lock_irq().raise(signal)
  309. }
  310. /// Handle signals in the context of `Thread::current()`.
  311. ///
  312. /// # Safety
  313. /// This function might never return. Caller must make sure that local variables
  314. /// that own resources are dropped before calling this function.
  315. pub fn handle(&self, int_stack: &mut InterruptContext, ext_ctx: &mut ExtendedContext) {
  316. loop {
  317. let signal = {
  318. let signal = match self.inner.lock_irq().pop() {
  319. Some(signal) => signal,
  320. None => return,
  321. };
  322. let handler = self.inner.lock_irq().handlers.get(&signal).cloned();
  323. if let Some(handler) = handler {
  324. if !signal.is_now() {
  325. let old_mask = {
  326. let mut inner = self.inner.lock_irq();
  327. let old_mask = inner.mask;
  328. inner.mask(handler.sa_mask as u64);
  329. old_mask
  330. };
  331. let result = handler.handle(signal, old_mask, int_stack, ext_ctx);
  332. if result.is_err() {
  333. self.inner.lock_irq().set_mask(old_mask);
  334. }
  335. match result {
  336. Err(EFAULT) => self.inner.lock_irq().raise(Signal::SIGSEGV),
  337. Err(_) => self.inner.lock_irq().raise(Signal::SIGSYS),
  338. Ok(()) => return,
  339. };
  340. continue;
  341. }
  342. }
  343. // TODO: The default signal handling process should be atomic.
  344. // Default actions include stopping the thread, continuing the thread and
  345. // terminating the process. All these actions will block the thread or return
  346. // to the thread immediately. So we can unmask these signals now.
  347. self.inner.lock_irq().unmask(signal.to_mask());
  348. signal
  349. };
  350. // Default actions.
  351. match signal {
  352. Signal::SIGSTOP | Signal::SIGTSTP | Signal::SIGTTIN | Signal::SIGTTOU => {
  353. let thread = Thread::current();
  354. if let Some(parent) = thread.process.parent.load() {
  355. parent.notify(
  356. WaitObject {
  357. pid: thread.process.pid,
  358. code: WaitType::Stopped(signal),
  359. },
  360. ProcessList::get().lock_shared().as_pos(),
  361. );
  362. }
  363. preempt::disable();
  364. // `SIGSTOP` can only be waken up by `SIGCONT` or `SIGKILL`.
  365. // SAFETY: Preempt disabled above.
  366. {
  367. let mut inner = self.inner.lock_irq();
  368. let waker = Waker::from(Task::current().usleep());
  369. let old_waker = inner.stop_waker.replace(waker);
  370. assert!(old_waker.is_none(), "We should not have a waker here");
  371. }
  372. Scheduler::schedule();
  373. if let Some(parent) = thread.process.parent.load() {
  374. parent.notify(
  375. WaitObject {
  376. pid: thread.process.pid,
  377. code: WaitType::Continued,
  378. },
  379. ProcessList::get().lock_shared().as_pos(),
  380. );
  381. }
  382. }
  383. Signal::SIGCONT => {}
  384. Signal::SIGKILL => ProcessList::kill_current(signal),
  385. // Ignored
  386. Signal::SIGCHLD | Signal::SIGURG | Signal::SIGWINCH => {}
  387. // TODO!!!!!!: Check exit status format.
  388. s if s.is_coredump() => ProcessList::kill_current(signal),
  389. signal => ProcessList::kill_current(signal),
  390. }
  391. }
  392. }
  393. /// Load the signal mask, MMX registers and interrupt stack from the user stack.
  394. /// We must be here because `sigreturn` is called. Se we return the value of the register
  395. /// used to store the syscall return value to prevent the original value being clobbered.
  396. pub fn restore(
  397. &self,
  398. int_stack: &mut InterruptContext,
  399. ext_ctx: &mut ExtendedContext,
  400. ) -> KResult<usize> {
  401. let old_mask_vaddr = int_stack.rsp as usize;
  402. let old_mmxregs_vaddr = old_mask_vaddr + size_of::<usize>();
  403. let old_int_stack_vaddr = old_mmxregs_vaddr + size_of::<ExtendedContext>();
  404. let old_mask = UserPointer::<u64>::new_vaddr(old_mask_vaddr)?.read()?;
  405. *ext_ctx = UserPointer::<ExtendedContext>::new_vaddr(old_mmxregs_vaddr)?.read()?;
  406. *int_stack = UserPointer::<InterruptContext>::new_vaddr(old_int_stack_vaddr)?.read()?;
  407. self.inner.lock_irq().set_mask(old_mask);
  408. Ok(int_stack.rax as usize)
  409. }
  410. }