From 7a08d9a660dedd13ba86ff8a9c4b8bdcfd47e3c1 Mon Sep 17 00:00:00 2001 From: Fabing Li Date: Fri, 1 Nov 2024 06:54:48 +0000 Subject: [PATCH] Support other SigStackFlags --- kernel/src/process/signal/sig_stack.rs | 22 +++++++------ kernel/src/syscall/sigaltstack.rs | 31 ++++++++++++++----- test/syscall_test/Makefile | 1 + test/syscall_test/blocklists/sigaltstack_test | 3 ++ 4 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 test/syscall_test/blocklists/sigaltstack_test diff --git a/kernel/src/process/signal/sig_stack.rs b/kernel/src/process/signal/sig_stack.rs index c077fd15..e98e332f 100644 --- a/kernel/src/process/signal/sig_stack.rs +++ b/kernel/src/process/signal/sig_stack.rs @@ -18,6 +18,8 @@ pub struct SigStack { bitflags! { pub struct SigStackFlags: u32 { + const SS_ONSTACK = 1 << 0; + const SS_DISABLE = 1 << 1; const SS_AUTODISARM = 1 << 31; } } @@ -57,16 +59,16 @@ impl SigStack { } pub fn status(&self) -> SigStackStatus { - if self.handler_counter == 0 { - return SigStackStatus::SS_INACTIVE; - } - // Learning From [sigaltstack doc](https://man7.org/linux/man-pages/man2/sigaltstack.2.html): // If the stack is currently executed on, // 1. If the stack was established with flag SS_AUTODISARM, the stack status is DISABLE, // 2. otherwise, the stack status is ONSTACK - if self.flags.contains(SigStackFlags::SS_AUTODISARM) { - SigStackStatus::SS_DISABLE + if self.handler_counter == 0 { + if self.flags.contains(SigStackFlags::SS_AUTODISARM) { + SigStackStatus::SS_DISABLE + } else { + SigStackStatus::SS_INACTIVE + } } else { SigStackStatus::SS_ONSTACK } @@ -85,11 +87,13 @@ impl SigStack { /// Determines whether the stack is executed on by any signal handler pub fn is_active(&self) -> bool { - // FIXME: can DISABLE stack be used? - self.handler_counter != 0 && !self.flags.contains(SigStackFlags::SS_AUTODISARM) + (self.handler_counter > 0) + && !(self.flags.intersects(SigStackFlags::SS_AUTODISARM) + || self.flags.intersects(SigStackFlags::SS_DISABLE)) } pub fn is_disabled(&self) -> bool { - self.handler_counter != 0 && self.flags.contains(SigStackFlags::SS_AUTODISARM) + self.flags.contains(SigStackFlags::SS_DISABLE) + || (self.handler_counter > 0 && self.flags.contains(SigStackFlags::SS_AUTODISARM)) } } diff --git a/kernel/src/syscall/sigaltstack.rs b/kernel/src/syscall/sigaltstack.rs index 97de9938..405a0a60 100644 --- a/kernel/src/syscall/sigaltstack.rs +++ b/kernel/src/syscall/sigaltstack.rs @@ -36,14 +36,23 @@ fn get_old_stack( return Ok(()); } - let Some(old_stack) = old_stack else { - return Ok(()); - }; + if let Some(old_stack) = old_stack { + debug!("old stack = {:?}", old_stack); - debug!("old stack = {:?}", old_stack); + let stack = stack_t::from(old_stack.clone()); + ctx.get_user_space() + .write_val::(old_sig_stack_addr, &stack)?; + } else { + let stack = stack_t { + sp: 0, + flags: SigStackFlags::SS_DISABLE.bits() as i32, + size: 0, + }; + ctx.get_user_space() + .write_val::(old_sig_stack_addr, &stack)?; + } - let stack = stack_t::from(old_stack.clone()); - ctx.get_user_space().write_val(old_sig_stack_addr, &stack) + Ok(()) } fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>, ctx: &Context) -> Result<()> { @@ -88,13 +97,20 @@ impl TryFrom for SigStack { return_errno_with_message!(Errno::EINVAL, "negative flags"); } - let flags = SigStackFlags::from_bits(stack.flags as u32) + let mut flags = SigStackFlags::from_bits(stack.flags as u32) .ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?; + if flags.contains(SigStackFlags::SS_DISABLE) { + return Ok(Self::new(0, flags, 0)); + } if stack.size < MINSTKSZ { return_errno_with_message!(Errno::ENOMEM, "stack size is less than MINSTKSZ"); } + if flags.is_empty() { + flags.insert(SigStackFlags::SS_ONSTACK); + } + Ok(Self::new(stack.sp, flags, stack.size)) } } @@ -102,6 +118,7 @@ impl TryFrom for SigStack { impl From for stack_t { fn from(stack: SigStack) -> Self { let flags = stack.flags().bits() as i32 | stack.status() as i32; + Self { sp: stack.base(), flags, diff --git a/test/syscall_test/Makefile b/test/syscall_test/Makefile index 97e484be..c39d0c5d 100644 --- a/test/syscall_test/Makefile +++ b/test/syscall_test/Makefile @@ -40,6 +40,7 @@ TESTS ?= \ rename_test \ semaphore_test \ sendfile_test \ + sigaltstack_test \ stat_test \ stat_times_test \ statfs_test \ diff --git a/test/syscall_test/blocklists/sigaltstack_test b/test/syscall_test/blocklists/sigaltstack_test new file mode 100644 index 00000000..cd562f5e --- /dev/null +++ b/test/syscall_test/blocklists/sigaltstack_test @@ -0,0 +1,3 @@ +SigaltstackTest.ResetByExecve +SigaltstackTest.WalksOffBottom +SigaltstackTest.SetCurrentStack \ No newline at end of file