Skip to content

Commit

Permalink
uucore: disable default signal-handlers added by Rust
Browse files Browse the repository at this point in the history
Fixes #6759

Test procedure (verifies that a single SIGSEGV stops a program):
```
ecordonnier@lj8k2dq3:~/dev/coreutils$ ./target/release/coreutils sleep 100 &
[1] 4175464
ecordonnier@lj8k2dq3:~/dev/coreutils$ kill -11 $(pidof coreutils)
ecordonnier@lj8k2dq3:~/dev/coreutils$
[1]+  Segmentation fault      (core dumped) ./target/release/coreutils sleep 100
```
  • Loading branch information
Ecordonnier committed Oct 21, 2024
1 parent 3f694fa commit 96d70d7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/uucore/src/lib/features/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (vars/api) fcntl setrlimit setitimer rubout pollable sysconf
// spell-checker:ignore (vars/api) fcntl setrlimit setitimer rubout pollable sysconf sigaction
// spell-checker:ignore (vars/signals) ABRT ALRM CHLD SEGV SIGABRT SIGALRM SIGBUS SIGCHLD SIGCONT SIGDANGER SIGEMT SIGFPE SIGHUP SIGILL SIGINFO SIGINT SIGIO SIGIOT SIGKILL SIGMIGRATE SIGMSG SIGPIPE SIGPRE SIGPROF SIGPWR SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTALRM SIGTERM SIGTRAP SIGTSTP SIGTHR SIGTTIN SIGTTOU SIGURG SIGUSR SIGVIRT SIGVTALRM SIGWINCH SIGXCPU SIGXFSZ STKFLT PWR THR TSTP TTIN TTOU VIRT VTALRM XCPU XFSZ SIGCLD SIGPOLL SIGWAITING SIGAIOCANCEL SIGLWP SIGFREEZE SIGTHAW SIGCANCEL SIGLOST SIGXRES SIGJVM SIGRTMIN SIGRT SIGRTMAX TALRM AIOCANCEL XRES RTMIN RTMAX

//! This module provides a way to handle signals in a platform-independent way.
Expand All @@ -14,7 +14,8 @@
use nix::errno::Errno;
#[cfg(unix)]
use nix::sys::signal::{
signal, SigHandler::SigDfl, SigHandler::SigIgn, Signal::SIGINT, Signal::SIGPIPE,
sigaction, signal, SaFlags, SigAction, SigHandler::SigDfl, SigHandler::SigIgn, SigSet,
Signal::SIGBUS, Signal::SIGINT, Signal::SIGPIPE, Signal::SIGSEGV,
};

/// The default signal value.
Expand Down Expand Up @@ -387,6 +388,25 @@ pub fn ignore_interrupts() -> Result<(), Errno> {
unsafe { signal(SIGINT, SigIgn) }.map(|_| ())
}

// Disables the custom signal handlers installed by Rust for stack-overflow handling. With those custom signal handlers processes ignore the first SIGBUS and SIGSEGV signal they receive.
// See https://github.com/rust-lang/rust/blob/8ac1525e091d3db28e67adcbbd6db1e1deaa37fb/src/libstd/sys/unix/stack_overflow.rs#L71-L92 for details.
#[cfg(unix)]
pub fn disable_rust_signal_handlers() -> Result<(), Errno> {
unsafe {
sigaction(
SIGSEGV,
&SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()),
)
}?;

Check warning on line 400 in src/uucore/src/lib/features/signals.rs

View check run for this annotation

Codecov / codecov/patch

src/uucore/src/lib/features/signals.rs#L400

Added line #L400 was not covered by tests
unsafe {
sigaction(
SIGBUS,
&SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()),
)
}?;

Check warning on line 406 in src/uucore/src/lib/features/signals.rs

View check run for this annotation

Codecov / codecov/patch

src/uucore/src/lib/features/signals.rs#L406

Added line #L406 was not covered by tests
Ok(())
}

#[test]
fn signal_by_value() {
assert_eq!(signal_by_name_or_value("0"), Some(0));
Expand Down
3 changes: 3 additions & 0 deletions src/uucore_procs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {

let new = quote!(
pub fn uumain(args: impl uucore::Args) -> i32 {
#[cfg(unix)]
uucore::signals::disable_rust_signal_handlers().expect("Disabling rust signal handlers failed");

#stream
let result = uumain(args);
match result {
Expand Down

0 comments on commit 96d70d7

Please sign in to comment.