@@ -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.
614654pub 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