diff --git a/src/main.rs b/src/main.rs index 92217ee8a..afcaa1a49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,7 @@ use std::thread; use thiserror::Error; use vmm::config; use vmm_sys_util::eventfd::EventFd; +use vmm_sys_util::signal::block_signal; #[derive(Error, Debug)] enum Error { @@ -496,6 +497,13 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result, Error> { .unwrap(); } + // Before we start any threads, mask the signals we'll be + // installing handlers for, to make sure they only ever run on the + // dedicated signal handling thread we'll start in a bit. + for sig in vmm::vm::HANDLED_SIGNALS { + block_signal(sig).unwrap(); + } + event!("vmm", "starting"); let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?; diff --git a/vmm/src/seccomp_filters.rs b/vmm/src/seccomp_filters.rs index 308c3cb96..f6069caf6 100644 --- a/vmm/src/seccomp_filters.rs +++ b/vmm/src/seccomp_filters.rs @@ -359,6 +359,7 @@ fn signal_handler_thread_rules() -> Result)>, Backend (libc::SYS_munmap, vec![]), (libc::SYS_recvfrom, vec![]), (libc::SYS_rt_sigprocmask, vec![]), + (libc::SYS_rt_sigreturn, vec![]), (libc::SYS_sendto, vec![]), (libc::SYS_sigaltstack, vec![]), (libc::SYS_write, vec![]), diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index ed3557e3b..21d04dd3e 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -76,6 +76,7 @@ use vm_migration::{ Transportable, }; use vmm_sys_util::eventfd::EventFd; +use vmm_sys_util::signal::unblock_signal; use vmm_sys_util::terminal::Terminal; #[cfg(target_arch = "aarch64")] @@ -465,6 +466,8 @@ pub fn physical_bits(max_phys_bits: Option, #[cfg(feature = "tdx")] tdx_enab cmp::min(host_phys_bits, max_phys_bits.unwrap_or(host_phys_bits)) } +pub const HANDLED_SIGNALS: [i32; 3] = [SIGWINCH, SIGTERM, SIGINT]; + pub struct Vm { kernel: Option, initramfs: Option, @@ -1591,6 +1594,10 @@ impl Vm { on_tty: bool, exit_evt: EventFd, ) { + for sig in HANDLED_SIGNALS { + unblock_signal(sig).unwrap(); + } + for signal in signals.forever() { match signal { SIGWINCH => { @@ -1867,7 +1874,7 @@ impl Vm { .input_enabled() { let console = self.device_manager.lock().unwrap().console().clone(); - let signals = Signals::new(&[SIGWINCH, SIGINT, SIGTERM]); + let signals = Signals::new(&HANDLED_SIGNALS); match signals { Ok(signals) => { self.signals = Some(signals.handle());