mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 16:33:24 +00:00
Support other SigStackFlags
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
561516df98
commit
7a08d9a660
@ -18,6 +18,8 @@ pub struct SigStack {
|
|||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct SigStackFlags: u32 {
|
pub struct SigStackFlags: u32 {
|
||||||
|
const SS_ONSTACK = 1 << 0;
|
||||||
|
const SS_DISABLE = 1 << 1;
|
||||||
const SS_AUTODISARM = 1 << 31;
|
const SS_AUTODISARM = 1 << 31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,16 +59,16 @@ impl SigStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn status(&self) -> SigStackStatus {
|
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):
|
// Learning From [sigaltstack doc](https://man7.org/linux/man-pages/man2/sigaltstack.2.html):
|
||||||
// If the stack is currently executed on,
|
// If the stack is currently executed on,
|
||||||
// 1. If the stack was established with flag SS_AUTODISARM, the stack status is DISABLE,
|
// 1. If the stack was established with flag SS_AUTODISARM, the stack status is DISABLE,
|
||||||
// 2. otherwise, the stack status is ONSTACK
|
// 2. otherwise, the stack status is ONSTACK
|
||||||
if self.flags.contains(SigStackFlags::SS_AUTODISARM) {
|
if self.handler_counter == 0 {
|
||||||
SigStackStatus::SS_DISABLE
|
if self.flags.contains(SigStackFlags::SS_AUTODISARM) {
|
||||||
|
SigStackStatus::SS_DISABLE
|
||||||
|
} else {
|
||||||
|
SigStackStatus::SS_INACTIVE
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SigStackStatus::SS_ONSTACK
|
SigStackStatus::SS_ONSTACK
|
||||||
}
|
}
|
||||||
@ -85,11 +87,13 @@ impl SigStack {
|
|||||||
|
|
||||||
/// Determines whether the stack is executed on by any signal handler
|
/// Determines whether the stack is executed on by any signal handler
|
||||||
pub fn is_active(&self) -> bool {
|
pub fn is_active(&self) -> bool {
|
||||||
// FIXME: can DISABLE stack be used?
|
(self.handler_counter > 0)
|
||||||
self.handler_counter != 0 && !self.flags.contains(SigStackFlags::SS_AUTODISARM)
|
&& !(self.flags.intersects(SigStackFlags::SS_AUTODISARM)
|
||||||
|
|| self.flags.intersects(SigStackFlags::SS_DISABLE))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_disabled(&self) -> bool {
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,23 @@ fn get_old_stack(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(old_stack) = old_stack else {
|
if let Some(old_stack) = old_stack {
|
||||||
return Ok(());
|
debug!("old stack = {:?}", old_stack);
|
||||||
};
|
|
||||||
|
|
||||||
debug!("old stack = {:?}", old_stack);
|
let stack = stack_t::from(old_stack.clone());
|
||||||
|
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)?;
|
||||||
|
}
|
||||||
|
|
||||||
let stack = stack_t::from(old_stack.clone());
|
Ok(())
|
||||||
ctx.get_user_space().write_val(old_sig_stack_addr, &stack)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>, ctx: &Context) -> Result<()> {
|
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");
|
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"))?;
|
.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 {
|
if stack.size < MINSTKSZ {
|
||||||
return_errno_with_message!(Errno::ENOMEM, "stack size is less than 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))
|
Ok(Self::new(stack.sp, flags, stack.size))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,6 +118,7 @@ impl TryFrom<stack_t> for SigStack {
|
|||||||
impl From<SigStack> for stack_t {
|
impl From<SigStack> for stack_t {
|
||||||
fn from(stack: SigStack) -> Self {
|
fn from(stack: SigStack) -> Self {
|
||||||
let flags = stack.flags().bits() as i32 | stack.status() as i32;
|
let flags = stack.flags().bits() as i32 | stack.status() as i32;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
sp: stack.base(),
|
sp: stack.base(),
|
||||||
flags,
|
flags,
|
||||||
|
@ -40,6 +40,7 @@ TESTS ?= \
|
|||||||
rename_test \
|
rename_test \
|
||||||
semaphore_test \
|
semaphore_test \
|
||||||
sendfile_test \
|
sendfile_test \
|
||||||
|
sigaltstack_test \
|
||||||
stat_test \
|
stat_test \
|
||||||
stat_times_test \
|
stat_times_test \
|
||||||
statfs_test \
|
statfs_test \
|
||||||
|
3
test/syscall_test/blocklists/sigaltstack_test
Normal file
3
test/syscall_test/blocklists/sigaltstack_test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SigaltstackTest.ResetByExecve
|
||||||
|
SigaltstackTest.WalksOffBottom
|
||||||
|
SigaltstackTest.SetCurrentStack
|
Reference in New Issue
Block a user