From b68eb04b8b67b19c1604e1cd75c6f011ce198361 Mon Sep 17 00:00:00 2001 From: Etienne Cordonnier Date: Sat, 19 Oct 2024 22:54:35 +0200 Subject: [PATCH] uucore: disable default signal-handlers added by Rust Fixes https://github.com/uutils/coreutils/issues/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 ``` --- src/uucore/src/lib/lib.rs | 27 +++++++++++++++++++++++++++ src/uucore_procs/src/lib.rs | 6 +++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index a636fcdab..6142e688d 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -4,6 +4,8 @@ // file that was distributed with this source code. //! library ~ (core/bundler file) // #![deny(missing_docs)] //TODO: enable this +// +// spell-checker:ignore sigaction SIGBUS SIGSEGV // * feature-gated external crates (re-shared as public internal modules) #[cfg(feature = "libc")] @@ -100,6 +102,12 @@ pub use crate::features::fsxattr; //## core functions +#[cfg(unix)] +use nix::errno::Errno; +#[cfg(unix)] +use nix::sys::signal::{ + sigaction, SaFlags, SigAction, SigHandler::SigDfl, SigSet, Signal::SIGBUS, Signal::SIGSEGV, +}; use std::borrow::Cow; use std::ffi::OsStr; use std::ffi::OsString; @@ -112,6 +120,25 @@ use std::sync::atomic::Ordering; use once_cell::sync::Lazy; +/// 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 for details. +#[cfg(unix)] +pub fn disable_rust_signal_handlers() -> Result<(), Errno> { + unsafe { + sigaction( + SIGSEGV, + &SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()), + ) + }?; + unsafe { + sigaction( + SIGBUS, + &SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()), + ) + }?; + Ok(()) +} + /// Execute utility code for `util`. /// /// This macro expands to a main function that invokes the `uumain` function in `util` diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index 11d89c97e..650417104 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -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 backticks uuhelp +// spell-checker:ignore backticks uuhelp SIGSEGV //! A collection of procedural macros for uutils. #![deny(missing_docs)] @@ -25,6 +25,10 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream { let new = quote!( pub fn uumain(args: impl uucore::Args) -> i32 { #stream + + // disable rust signal handlers (otherwise processes don't dump core after e.g. one SIGSEGV) + #[cfg(unix)] + uucore::disable_rust_signal_handlers().expect("Disabling rust signal handlers failed"); let result = uumain(args); match result { Ok(()) => uucore::error::get_exit_code(),