@@ -584,9 +584,31 @@ impl SigAction {
584
584
match self . sigaction . sa_sigaction {
585
585
libc:: SIG_DFL => SigHandler :: SigDfl ,
586
586
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 ) ) ,
590
612
}
591
613
}
592
614
@@ -596,7 +618,18 @@ impl SigAction {
596
618
match self . sigaction . sa_handler {
597
619
libc:: SIG_DFL => SigHandler :: SigDfl ,
598
620
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 ) ) ,
600
633
}
601
634
}
602
635
}
@@ -608,9 +641,16 @@ impl SigAction {
608
641
///
609
642
/// # Safety
610
643
///
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.
614
654
pub unsafe fn sigaction ( signal : Signal , sigaction : & SigAction ) -> Result < SigAction > {
615
655
let mut oldact = mem:: MaybeUninit :: < libc:: sigaction > :: uninit ( ) ;
616
656
@@ -689,7 +729,10 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
689
729
match oldhandler {
690
730
libc:: SIG_DFL => SigHandler :: SigDfl ,
691
731
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 ) ) ,
693
736
}
694
737
} )
695
738
}
0 commit comments