Support other SigStackFlags

This commit is contained in:
Fabing Li
2024-11-01 06:54:48 +00:00
committed by Tate, Hongliang Tian
parent 561516df98
commit 7a08d9a660
4 changed files with 41 additions and 16 deletions

View File

@ -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.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))
}
}

View File

@ -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);
let stack = stack_t::from(old_stack.clone());
ctx.get_user_space().write_val(old_sig_stack_addr, &stack)
ctx.get_user_space()
.write_val::<stack_t>(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::<stack_t>(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<stack_t> 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<stack_t> for SigStack {
impl From<SigStack> for stack_t {
fn from(stack: SigStack) -> Self {
let flags = stack.flags().bits() as i32 | stack.status() as i32;
Self {
sp: stack.base(),
flags,

View File

@ -40,6 +40,7 @@ TESTS ?= \
rename_test \
semaphore_test \
sendfile_test \
sigaltstack_test \
stat_test \
stat_times_test \
statfs_test \

View File

@ -0,0 +1,3 @@
SigaltstackTest.ResetByExecve
SigaltstackTest.WalksOffBottom
SigaltstackTest.SetCurrentStack