Set uc_stack properly.

POSIX does not appear to explicitly mention that this should be the
sigaltstack, but other Linux appears to treat it as the sigaltstack.
This commit is contained in:
4lDO2
2024-08-02 16:18:24 +02:00
parent 30caf55429
commit 09108634cf
4 changed files with 62 additions and 31 deletions
+5 -6
View File
@@ -12,7 +12,10 @@ use syscall::{
use crate::{
proc::{fork_inner, FdGuard},
signal::{inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
signal::{
get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack, Sigaltstack,
PROC_CONTROL_STRUCT,
},
RtTcb, Tcb,
};
@@ -452,11 +455,7 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt
stack.regs.rip = area.tmp_rip;
}
PosixStackt {
sp: stack.regs.rsp as *mut (),
size: 0, // TODO
flags: 0, // TODO
}
get_sigaltstack(area, stack.regs.rsp).into()
}
pub(crate) static SUPPORTS_AVX: AtomicU8 = AtomicU8::new(0);
+42 -9
View File
@@ -52,6 +52,34 @@ pub struct PosixStackt {
pub size: usize,
}
pub const SS_ONSTACK: usize = 1;
pub const SS_DISABLE: usize = 2;
impl From<Sigaltstack> for PosixStackt {
fn from(value: Sigaltstack) -> Self {
match value {
Sigaltstack::Disabled => PosixStackt {
sp: core::ptr::null_mut(),
size: 0,
flags: SS_DISABLE.try_into().unwrap(),
},
Sigaltstack::Enabled {
onstack,
base,
size,
} => PosixStackt {
sp: base.cast(),
size,
flags: if onstack {
SS_ONSTACK.try_into().unwrap()
} else {
0
},
},
}
}
}
#[repr(C)]
// TODO: This struct is for practical reasons locked to Linux's ABI, but avoid redefining
// it here. Alternatively, check at compile time that the structs are equivalent.
@@ -590,6 +618,19 @@ pub enum Sigaltstack {
size: usize,
},
}
pub(crate) fn get_sigaltstack(tcb: &SigArea, sp: usize) -> Sigaltstack {
if tcb.altstack_bottom == 0 && tcb.altstack_top == usize::MAX {
Sigaltstack::Disabled
} else {
Sigaltstack::Enabled {
base: tcb.altstack_bottom as *mut (),
size: tcb.altstack_top - tcb.altstack_bottom,
onstack: (tcb.altstack_bottom..tcb.altstack_top).contains(&sp),
}
}
}
pub unsafe fn sigaltstack(
new: Option<&Sigaltstack>,
old_out: Option<&mut Sigaltstack>,
@@ -597,15 +638,7 @@ pub unsafe fn sigaltstack(
let _g = tmp_disable_signals();
let tcb = &mut *Tcb::current().unwrap().os_specific.arch.get();
let old = if tcb.altstack_bottom == 0 && tcb.altstack_top == usize::MAX {
Sigaltstack::Disabled
} else {
Sigaltstack::Enabled {
base: tcb.altstack_bottom as *mut (),
size: tcb.altstack_top - tcb.altstack_bottom,
onstack: (tcb.altstack_bottom..tcb.altstack_top).contains(&crate::arch::current_sp()),
}
};
let old = get_sigaltstack(tcb, crate::arch::current_sp());
if matches!(old, Sigaltstack::Enabled { onstack: true, .. }) && new != Some(&old) {
return Err(Error::new(EPERM));
+9
View File
@@ -50,6 +50,15 @@ pub const SA_NOCLDSTOP: usize = 0x4000_0000;
pub const SS_ONSTACK: usize = 0x00000001;
pub const SS_DISABLE: usize = 0x00000002;
const _: () = {
if SS_ONSTACK != redox_rt::signal::SS_ONSTACK {
panic!();
}
if SS_DISABLE != redox_rt::signal::SS_DISABLE {
panic!();
}
};
// TODO: It's just a guess based on Linux
pub const MINSIGSTKSZ: usize = 2048;
pub const SIGSTKSZ: usize = 8096;
+6 -16
View File
@@ -1,6 +1,6 @@
use core::mem::{self, offset_of};
use redox_rt::signal::{
SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler,
PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler,
};
use syscall::{self, Result};
@@ -235,21 +235,11 @@ impl PalSignal for Sys {
redox_rt::signal::sigaltstack(new.as_ref(), old.as_mut())?;
if let (Some(old_c_stack), Some(old)) = (old_c, old) {
*old_c_stack = match old {
Sigaltstack::Disabled => stack_t {
ss_sp: core::ptr::null_mut(),
ss_size: 0,
ss_flags: SS_DISABLE.try_into().unwrap(),
},
Sigaltstack::Enabled {
onstack,
base,
size,
} => stack_t {
ss_sp: base.cast(),
ss_size: size,
ss_flags: SS_ONSTACK.try_into().unwrap(),
},
let c_stack = PosixStackt::from(old);
*old_c_stack = stack_t {
ss_sp: c_stack.sp.cast(),
ss_size: c_stack.size,
ss_flags: c_stack.flags,
};
}
Ok(())