Skip to content

Commit 2df8679

Browse files
bors[bot]asomers
andauthored
Merge #1485
1485: Replace some mem::transmute calls in signal.rs with pointer casts r=asomers a=asomers Issue #373 Co-authored-by: Alan Somers <[email protected]>
2 parents 68488a4 + 8af3414 commit 2df8679

File tree

1 file changed

+51
-8
lines changed

1 file changed

+51
-8
lines changed

src/sys/signal.rs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -584,9 +584,31 @@ impl SigAction {
584584
match self.sigaction.sa_sigaction {
585585
libc::SIG_DFL => SigHandler::SigDfl,
586586
libc::SIG_IGN => SigHandler::SigIgn,
587-
f if self.flags().contains(SaFlags::SA_SIGINFO) =>
588-
SigHandler::SigAction( unsafe { mem::transmute(f) } ),
589-
f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
587+
p if self.flags().contains(SaFlags::SA_SIGINFO) =>
588+
SigHandler::SigAction(
589+
// Safe for one of two reasons:
590+
// * The SigHandler was created by SigHandler::new, in which
591+
// case the pointer is correct, or
592+
// * The SigHandler was created by signal or sigaction, which
593+
// are unsafe functions, so the caller should've somehow
594+
// ensured that it is correctly initialized.
595+
unsafe{
596+
*(&p as *const usize
597+
as *const extern fn(_, _, _))
598+
}
599+
as extern fn(_, _, _)),
600+
p => SigHandler::Handler(
601+
// Safe for one of two reasons:
602+
// * The SigHandler was created by SigHandler::new, in which
603+
// case the pointer is correct, or
604+
// * The SigHandler was created by signal or sigaction, which
605+
// are unsafe functions, so the caller should've somehow
606+
// ensured that it is correctly initialized.
607+
unsafe{
608+
*(&p as *const usize
609+
as *const extern fn(libc::c_int))
610+
}
611+
as extern fn(libc::c_int)),
590612
}
591613
}
592614

@@ -596,7 +618,18 @@ impl SigAction {
596618
match self.sigaction.sa_handler {
597619
libc::SIG_DFL => SigHandler::SigDfl,
598620
libc::SIG_IGN => SigHandler::SigIgn,
599-
f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
621+
p => SigHandler::Handler(
622+
// Safe for one of two reasons:
623+
// * The SigHandler was created by SigHandler::new, in which
624+
// case the pointer is correct, or
625+
// * The SigHandler was created by signal or sigaction, which
626+
// are unsafe functions, so the caller should've somehow
627+
// ensured that it is correctly initialized.
628+
unsafe{
629+
*(&p as *const usize
630+
as *const extern fn(libc::c_int))
631+
}
632+
as extern fn(libc::c_int)),
600633
}
601634
}
602635
}
@@ -608,9 +641,16 @@ impl SigAction {
608641
///
609642
/// # Safety
610643
///
611-
/// Signal handlers may be called at any point during execution, which limits what is safe to do in
612-
/// the body of the signal-catching function. Be certain to only make syscalls that are explicitly
613-
/// marked safe for signal handlers and only share global data using atomics.
644+
/// * Signal handlers may be called at any point during execution, which limits
645+
/// what is safe to do in the body of the signal-catching function. Be certain
646+
/// to only make syscalls that are explicitly marked safe for signal handlers
647+
/// and only share global data using atomics.
648+
///
649+
/// * There is also no guarantee that the old signal handler was installed
650+
/// correctly. If it was installed by this crate, it will be. But if it was
651+
/// installed by, for example, C code, then there is no guarantee its function
652+
/// pointer is valid. In that case, this function effectively dereferences a
653+
/// raw pointer of unknown provenance.
614654
pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
615655
let mut oldact = mem::MaybeUninit::<libc::sigaction>::uninit();
616656

@@ -689,7 +729,10 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
689729
match oldhandler {
690730
libc::SIG_DFL => SigHandler::SigDfl,
691731
libc::SIG_IGN => SigHandler::SigIgn,
692-
f => SigHandler::Handler(mem::transmute(f)),
732+
p => SigHandler::Handler(
733+
*(&p as *const usize
734+
as *const extern fn(libc::c_int))
735+
as extern fn(libc::c_int)),
693736
}
694737
})
695738
}

0 commit comments

Comments
 (0)