1use super::error::SyscallError;
4use crate::{
5 memory::{UserSliceRead, UserSliceWrite},
6 process::{
7 current_pgid, current_task_clone, current_task_id, get_all_tasks, get_task_by_id,
8 get_task_id_by_pid, get_task_ids_in_pgid,
9 signal::{SigActionData, SigStack, Signal},
10 TaskId,
11 },
12};
13
14pub fn sys_sigaction(signum: u64, act_ptr: u64, oact_ptr: u64) -> Result<u64, SyscallError> {
16 use core::mem;
17
18 let signal = Signal::from_u32(signum as u32).ok_or(SyscallError::InvalidArgument)?;
19 if signal.is_uncatchable() {
20 return Err(SyscallError::InvalidArgument);
21 }
22
23 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
24
25 unsafe {
26 let actions = &mut *task.process.signal_actions.get();
27
28 if oact_ptr != 0 {
29 let old = actions[signum as usize];
30 let raw = SigActionRaw {
31 sa_handler: old.handler,
32 sa_flags: old.flags,
33 sa_restorer: old.restorer,
34 sa_mask: old.mask,
35 };
36 let user = UserSliceWrite::new(oact_ptr, mem::size_of::<SigActionRaw>())?;
37 user.copy_from(&raw.to_bytes());
38 }
39
40 if act_ptr != 0 {
41 let user = UserSliceRead::new(act_ptr, mem::size_of::<SigActionRaw>())?;
42 let bytes = user.read_to_vec();
43 if bytes.len() != mem::size_of::<SigActionRaw>() {
44 return Err(SyscallError::InvalidArgument);
45 }
46 let raw = SigActionRaw::from_bytes(&bytes);
47 actions[signum as usize] = SigActionData {
48 handler: raw.sa_handler,
49 flags: raw.sa_flags,
50 restorer: raw.sa_restorer,
51 mask: raw.sa_mask,
52 };
53 }
54 }
55
56 Ok(0)
57}
58
59#[repr(C)]
61struct SigActionRaw {
62 sa_handler: u64,
63 sa_flags: u64,
64 sa_restorer: u64,
65 sa_mask: u64,
66}
67
68impl SigActionRaw {
69 fn to_bytes(&self) -> [u8; 32] {
71 let mut bytes = [0u8; 32];
72 bytes[0..8].copy_from_slice(&self.sa_handler.to_ne_bytes());
73 bytes[8..16].copy_from_slice(&self.sa_flags.to_ne_bytes());
74 bytes[16..24].copy_from_slice(&self.sa_restorer.to_ne_bytes());
75 bytes[24..32].copy_from_slice(&self.sa_mask.to_ne_bytes());
76 bytes
77 }
78
79 fn from_bytes(bytes: &[u8]) -> Self {
81 Self {
82 sa_handler: u64::from_ne_bytes(bytes[0..8].try_into().unwrap()),
83 sa_flags: u64::from_ne_bytes(bytes[8..16].try_into().unwrap()),
84 sa_restorer: u64::from_ne_bytes(bytes[16..24].try_into().unwrap()),
85 sa_mask: u64::from_ne_bytes(bytes[24..32].try_into().unwrap()),
86 }
87 }
88}
89
90pub fn sys_sigaltstack(ss_ptr: u64, old_ss_ptr: u64) -> Result<u64, SyscallError> {
94 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
95
96 unsafe {
98 let stack = &mut *task.signal_stack.get();
99
100 if old_ss_ptr != 0 {
102 let user = UserSliceWrite::new(old_ss_ptr, 24)?; let raw = match stack {
104 Some(s) => SigStackRaw {
105 ss_sp: s.ss_sp,
106 ss_flags: s.ss_flags,
107 ss_size: s.ss_size,
108 },
109 None => SigStackRaw {
110 ss_sp: 0,
111 ss_flags: 1, ss_size: 0,
113 },
114 };
115 user.copy_from(&raw.to_bytes());
116 }
117
118 if ss_ptr != 0 {
120 let user = UserSliceRead::new(ss_ptr, 24)?;
121 let bytes = user.read_to_vec();
122 if bytes.len() != 24 {
123 return Err(SyscallError::InvalidArgument);
124 }
125 let raw = SigStackRaw::from_bytes(&bytes);
126
127 if raw.ss_flags & 1 != 0 {
128 *stack = None;
130 } else {
131 *stack = Some(SigStack {
132 ss_sp: raw.ss_sp,
133 ss_flags: raw.ss_flags,
134 ss_size: raw.ss_size,
135 });
136 }
137 }
138 }
139
140 Ok(0)
141}
142
143#[repr(C)]
144struct SigStackRaw {
145 ss_sp: u64,
146 ss_flags: i32,
147 ss_size: usize,
148}
149
150impl SigStackRaw {
151 fn to_bytes(&self) -> [u8; 24] {
153 let mut bytes = [0u8; 24];
154 bytes[0..8].copy_from_slice(&self.ss_sp.to_ne_bytes());
155 bytes[8..12].copy_from_slice(&self.ss_flags.to_ne_bytes());
156 bytes[12..16].copy_from_slice(&(self.ss_size as u32).to_ne_bytes());
157 bytes[16..20].copy_from_slice(&((self.ss_size >> 32) as u32).to_ne_bytes());
158 bytes
159 }
160
161 fn from_bytes(bytes: &[u8]) -> Self {
163 Self {
164 ss_sp: u64::from_ne_bytes(bytes[0..8].try_into().unwrap()),
165 ss_flags: i32::from_ne_bytes(bytes[8..12].try_into().unwrap()),
166 ss_size: (u32::from_ne_bytes(bytes[12..16].try_into().unwrap()) as usize)
167 | ((u32::from_ne_bytes(bytes[16..20].try_into().unwrap()) as usize) << 32),
168 }
169 }
170}
171
172pub fn sys_sigpending(set_ptr: u64) -> Result<u64, SyscallError> {
176 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
177
178 let pending = &task.pending_signals;
180 let mask = pending.get_mask();
181
182 if set_ptr != 0 {
183 let user = UserSliceWrite::new(set_ptr, 8)?;
184 user.copy_from(&mask.to_ne_bytes());
185 }
186
187 Ok(0)
188}
189
190pub fn sys_sigsuspend(mask_ptr: u64) -> Result<u64, SyscallError> {
195 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
196
197 let blocked = &task.blocked_signals;
200 let old_mask = blocked.get_mask();
201
202 if mask_ptr != 0 {
204 let user = UserSliceRead::new(mask_ptr, 8)?;
205 let mut buf = [0u8; 8];
206 user.copy_to(&mut buf);
207 let new_mask = u64::from_ne_bytes(buf);
208 blocked.set_mask(new_mask);
209 }
210
211 crate::process::block_current_task();
214
215 blocked.set_mask(old_mask);
217
218 Err(SyscallError::Interrupted)
220}
221
222pub fn sys_sigtimedwait(
226 set_ptr: u64,
227 _siginfo_ptr: u64,
228 _timeout_ptr: u64,
229) -> Result<u64, SyscallError> {
230 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
234
235 let pending = &task.pending_signals;
237 let blocked = &task.blocked_signals;
238
239 if set_ptr != 0 {
241 let user = UserSliceRead::new(set_ptr, 8)?;
242 let mut buf = [0u8; 8];
243 user.copy_to(&mut buf);
244 let wait_mask = u64::from_ne_bytes(buf);
245
246 let pending_mask = pending.get_mask();
248 let blocked_mask = blocked.get_mask();
249 let deliverable = pending_mask & wait_mask & !blocked_mask;
250
251 if deliverable != 0 {
252 let signal_num = deliverable.trailing_zeros() + 1;
254 pending.remove(Signal::from_u32(signal_num).unwrap());
255 return Ok(signal_num as u64);
256 }
257 }
258
259 Err(SyscallError::Interrupted)
261}
262
263pub fn sys_sigqueue(pid: i64, signum: u32, _sigval_ptr: u64) -> Result<u64, SyscallError> {
267 sys_kill(pid, signum)
269}
270
271pub fn sys_killpg(pgrp: u64, signum: u32) -> Result<u64, SyscallError> {
275 if pgrp == 0 {
276 return Err(SyscallError::InvalidArgument);
277 }
278 sys_kill(-(pgrp as i64), signum)
279}
280
281pub fn sys_kill(pid: i64, signum: u32) -> Result<u64, SyscallError> {
283 let targets = resolve_kill_targets(pid)?;
284 let sender = current_task_clone().ok_or(SyscallError::Fault)?;
285 if signum == 0 {
286 for target in &targets {
288 if !has_kill_permission(&sender, *target)? {
289 return Err(SyscallError::PermissionDenied);
290 }
291 }
292 return Ok(0);
293 }
294
295 let signal = Signal::from_u32(signum).ok_or(SyscallError::InvalidArgument)?;
296 let mut delivered = 0usize;
297 for target in targets {
298 if !has_kill_permission(&sender, target)? {
299 continue;
300 }
301 crate::process::send_signal(target, signal)?;
302 delivered += 1;
303 }
304 if delivered == 0 {
305 return Err(SyscallError::PermissionDenied);
306 }
307 Ok(0)
308}
309
310fn has_kill_permission(
312 sender: &alloc::sync::Arc<crate::process::Task>,
313 target_id: TaskId,
314) -> Result<bool, SyscallError> {
315 let target = get_task_by_id(target_id).ok_or(SyscallError::NotFound)?;
316
317 let sender_euid = sender.euid.load(core::sync::atomic::Ordering::Relaxed);
318 if sender_euid == 0 {
319 return Ok(true);
320 }
321
322 let sender_uid = sender.uid.load(core::sync::atomic::Ordering::Relaxed);
323 let target_uid = target.uid.load(core::sync::atomic::Ordering::Relaxed);
324 let target_euid = target.euid.load(core::sync::atomic::Ordering::Relaxed);
325 Ok(sender_uid == target_uid
326 || sender_uid == target_euid
327 || sender_euid == target_uid
328 || sender_euid == target_euid)
329}
330
331fn resolve_kill_targets(pid: i64) -> Result<alloc::vec::Vec<TaskId>, SyscallError> {
333 use alloc::vec::Vec;
334
335 let mut targets = Vec::new();
336 match pid {
337 p if p > 0 => {
338 let target = get_task_id_by_pid(p as u32).ok_or(SyscallError::NotFound)?;
339 targets.push(target);
340 }
341 0 => {
342 let pgid = current_pgid().ok_or(SyscallError::Fault)?;
343 targets = get_task_ids_in_pgid(pgid);
344 }
345 -1 => {
346 let me = current_task_id();
347 if let Some(tasks) = get_all_tasks() {
348 for task in tasks {
349 if task.is_kernel() {
350 continue;
351 }
352 if Some(task.id) == me {
353 continue;
354 }
355 targets.push(task.id);
356 }
357 }
358 }
359 p => {
360 let pgid = (-p) as u32;
361 targets = get_task_ids_in_pgid(pgid);
362 }
363 }
364
365 if targets.is_empty() {
366 return Err(SyscallError::NotFound);
367 }
368 Ok(targets)
369}
370
371pub fn sys_getitimer(which: u32, value_ptr: u64) -> Result<u64, SyscallError> {
375 use crate::process::timer::{ITimerVal, ITimerWhich};
376 use core::mem;
377
378 let which = ITimerWhich::from_u32(which).ok_or(SyscallError::InvalidArgument)?;
379 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
380
381 let current_time_ns = 0u64;
384
385 let timer = task.itimers.get(which);
386 let value = timer.get(current_time_ns);
387
388 if value_ptr != 0 {
389 let user = UserSliceWrite::new(value_ptr, mem::size_of::<ITimerVal>())?;
390 user.copy_from(&itimerval_to_bytes(&value));
391 }
392
393 Ok(0)
394}
395
396pub fn sys_setitimer(
400 which: u32,
401 new_value_ptr: u64,
402 old_value_ptr: u64,
403) -> Result<u64, SyscallError> {
404 use crate::process::timer::{ITimerVal, ITimerWhich};
405 use core::mem;
406
407 let which = ITimerWhich::from_u32(which).ok_or(SyscallError::InvalidArgument)?;
408 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
409
410 let current_time_ns = crate::syscall::time::current_time_ns();
411
412 let timer = task.itimers.get(which);
413
414 if old_value_ptr != 0 {
416 let old_value = timer.get(current_time_ns);
417 let user = UserSliceWrite::new(old_value_ptr, mem::size_of::<ITimerVal>())?;
418 user.copy_from(&itimerval_to_bytes(&old_value));
419 }
420
421 if new_value_ptr != 0 {
423 let user = UserSliceRead::new(new_value_ptr, mem::size_of::<ITimerVal>())?;
424 let bytes = user.read_to_vec();
425 if bytes.len() != mem::size_of::<ITimerVal>() {
426 return Err(SyscallError::InvalidArgument);
427 }
428 let new_value = itimerval_from_bytes(&bytes);
429 let valid = |sec: i64, usec: i64| sec >= 0 && (0..1_000_000).contains(&usec);
430 if !valid(new_value.it_interval.tv_sec, new_value.it_interval.tv_usec)
431 || !valid(new_value.it_value.tv_sec, new_value.it_value.tv_usec)
432 {
433 return Err(SyscallError::InvalidArgument);
434 }
435 timer.set(&new_value, current_time_ns);
436 }
437
438 Ok(0)
439}
440
441fn itimerval_to_bytes(val: &crate::process::timer::ITimerVal) -> [u8; 32] {
443 let mut bytes = [0u8; 32];
444 bytes[0..8].copy_from_slice(&val.it_interval.tv_sec.to_ne_bytes());
446 bytes[8..16].copy_from_slice(&val.it_interval.tv_usec.to_ne_bytes());
447 bytes[16..24].copy_from_slice(&val.it_value.tv_sec.to_ne_bytes());
449 bytes[24..32].copy_from_slice(&val.it_value.tv_usec.to_ne_bytes());
450 bytes
451}
452
453fn itimerval_from_bytes(bytes: &[u8]) -> crate::process::timer::ITimerVal {
455 use crate::process::timer::{ITimerVal, TimeVal};
456 ITimerVal {
457 it_interval: TimeVal {
458 tv_sec: i64::from_ne_bytes(bytes[0..8].try_into().unwrap()),
459 tv_usec: i64::from_ne_bytes(bytes[8..16].try_into().unwrap()),
460 },
461 it_value: TimeVal {
462 tv_sec: i64::from_ne_bytes(bytes[16..24].try_into().unwrap()),
463 tv_usec: i64::from_ne_bytes(bytes[24..32].try_into().unwrap()),
464 },
465 }
466}
467
468pub fn sys_rt_sigreturn(frame: &mut super::SyscallFrame) -> Result<u64, SyscallError> {
470 use crate::process::signal::{SignalFrame, SIGNAL_FRAME_MAGIC};
471
472 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
473 let user_rsp = frame.iret_rsp;
474
475 let frame_size = core::mem::size_of::<SignalFrame>();
476 let sig_frame_addr = user_rsp - 8; let user = UserSliceRead::new(sig_frame_addr, frame_size)?;
479 let bytes = user.read_to_vec();
480 if bytes.len() != frame_size {
481 return Err(SyscallError::Fault);
482 }
483
484 let sig_frame: SignalFrame =
486 unsafe { core::ptr::read_unaligned(bytes.as_ptr() as *const SignalFrame) };
487
488 if sig_frame.magic != SIGNAL_FRAME_MAGIC {
489 log::warn!("[sigreturn] bad magic, killing");
490 crate::process::kill_task(task.id);
491 return Err(SyscallError::Fault);
492 }
493
494 task.blocked_signals.set_mask(sig_frame.saved_mask);
495
496 frame.iret_rip = sig_frame.rip;
497 frame.iret_rsp = sig_frame.rsp;
498 frame.iret_rflags = sig_frame.rflags;
499 frame.rax = sig_frame.rax;
500 frame.rcx = sig_frame.rcx;
501 frame.rdx = sig_frame.rdx;
502 frame.rbx = sig_frame.rbx;
503 frame.rbp = sig_frame.rbp;
504 frame.rsi = sig_frame.rsi;
505 frame.rdi = sig_frame.rdi;
506 frame.r8 = sig_frame.r8;
507 frame.r9 = sig_frame.r9;
508 frame.r10 = sig_frame.r10;
509 frame.r11 = sig_frame.r11;
510 frame.r12 = sig_frame.r12;
511 frame.r13 = sig_frame.r13;
512 frame.r14 = sig_frame.r14;
513 frame.r15 = sig_frame.r15;
514
515 Ok(frame.rax)
516}