Skip to content
Snippets Groups Projects
Commit 0a558de7 authored by AdminXVII's avatar AdminXVII
Browse files

Fix reference getting moved

The sigaction handler called map on an option, creating a pointer to a
move value. This in turned caused UB for signal handlers. Avoid using
pointers directly, and instead prefer references.
parent 22558323
No related branches found
No related tags found
No related merge requests found
//! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html //! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
use core::{mem, ptr}; use core::mem;
use cbitset::BitSet; use cbitset::BitSet;
...@@ -21,9 +21,9 @@ pub mod sys; ...@@ -21,9 +21,9 @@ pub mod sys;
type SigSet = BitSet<[c_ulong; 1]>; type SigSet = BitSet<[c_ulong; 1]>;
pub (crate) const SIG_DFL: usize = 0; pub(crate) const SIG_DFL: usize = 0;
pub (crate) const SIG_IGN: usize = 1; pub(crate) const SIG_IGN: usize = 1;
pub (crate) const SIG_ERR: isize = -1; pub(crate) const SIG_ERR: isize = -1;
pub const SIG_BLOCK: c_int = 0; pub const SIG_BLOCK: c_int = 0;
pub const SIG_UNBLOCK: c_int = 1; pub const SIG_UNBLOCK: c_int = 1;
...@@ -86,18 +86,12 @@ pub unsafe extern "C" fn sigaction( ...@@ -86,18 +86,12 @@ pub unsafe extern "C" fn sigaction(
act: *const sigaction, act: *const sigaction,
oact: *mut sigaction, oact: *mut sigaction,
) -> c_int { ) -> c_int {
let act_opt = if !act.is_null() { let act_opt = act.as_ref().map(|act| {
let mut act_clone = (*act).clone(); let mut act_clone = act.clone();
act_clone.sa_flags |= SA_RESTORER as c_ulong; act_clone.sa_flags |= SA_RESTORER as c_ulong;
Some(act_clone) act_clone
} else { });
None Sys::sigaction(sig, act_opt.as_ref(), oact.as_mut())
};
println!("sig => {:?}", act_opt);
println!("osig => {:?}", (*oact));
let out = Sys::sigaction(sig, act_opt.map_or(ptr::null_mut(), |x| &x), oact);
println!("aosig => {:?}", (*oact).sa_handler);
out
} }
#[no_mangle] #[no_mangle]
...@@ -198,8 +192,10 @@ extern "C" { ...@@ -198,8 +192,10 @@ extern "C" {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn signal(sig: c_int, func: Option<extern "C" fn(c_int)>) -> Option<extern "C" fn(c_int)> { pub extern "C" fn signal(
println!("{:?}", func); sig: c_int,
func: Option<extern "C" fn(c_int)>,
) -> Option<extern "C" fn(c_int)> {
let sa = sigaction { let sa = sigaction {
sa_handler: func, sa_handler: func,
sa_flags: SA_RESTART as c_ulong, sa_flags: SA_RESTART as c_ulong,
......
...@@ -35,15 +35,16 @@ impl PalSignal for Sys { ...@@ -35,15 +35,16 @@ impl PalSignal for Sys {
e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
} }
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int { fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int {
println!("in: {:?}", (*act)); e(unsafe {
e(syscall!( syscall!(
RT_SIGACTION, RT_SIGACTION,
sig, sig,
act, act.map_or_else(core::ptr::null, |x| x as *const _),
oact, oact.map_or_else(core::ptr::null_mut, |x| x as *mut _),
mem::size_of::<sigset_t>() mem::size_of::<sigset_t>()
)) as c_int )
}) as c_int
} }
fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int {
......
...@@ -15,7 +15,7 @@ pub trait PalSignal: Pal { ...@@ -15,7 +15,7 @@ pub trait PalSignal: Pal {
fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int; fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int;
unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int; fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int;
fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int; fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int;
......
...@@ -111,7 +111,9 @@ impl PalSignal for Sys { ...@@ -111,7 +111,9 @@ impl PalSignal for Sys {
} else { } else {
let m = (*act).sa_mask; let m = (*act).sa_mask;
let sa_handler = mem::transmute((*act).sa_handler); let sa_handler = mem::transmute((*act).sa_handler);
println!("signal called with {:x}", unsafe { mem::transmute::<_, usize>(sa_handler) }); println!("signal called with {:x}", unsafe {
mem::transmute::<_, usize>(sa_handler)
});
Some(syscall::SigAction { Some(syscall::SigAction {
sa_handler, sa_handler,
sa_mask: [m as u64, 0], sa_mask: [m as u64, 0],
...@@ -138,7 +140,7 @@ impl PalSignal for Sys { ...@@ -138,7 +140,7 @@ impl PalSignal for Sys {
(*oact).sa_mask = m[0] as c_ulong; (*oact).sa_mask = m[0] as c_ulong;
(*oact).sa_flags = old.sa_flags.bits() as c_ulong; (*oact).sa_flags = old.sa_flags.bits() as c_ulong;
} }
println!("after : {:?}", oact); println!("after : {:?}", (*oact));
ret ret
} }
......
...@@ -11,12 +11,10 @@ void handler(int sig) { ...@@ -11,12 +11,10 @@ void handler(int sig) {
} }
int main(void) { int main(void) {
printf("handler: %x\n", handler);
void (*signal_status)(int) = signal(SIGUSR1, handler); void (*signal_status)(int) = signal(SIGUSR1, handler);
ERROR_IF(signal, signal_status, == SIG_ERR); ERROR_IF(signal, signal_status, == SIG_ERR);
signal_status = signal(SIGUSR1, handler); signal_status = signal(SIGUSR1, handler);
ERROR_IF(signal, signal_status, == SIG_ERR); ERROR_IF(signal, signal_status, != handler);
printf("out: %x\n", signal_status);
puts("Raising..."); puts("Raising...");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment