sys_util: allow adding handlers for all signals

Currently, sys_util's register_signal_handler only permits handlers for
real-time signals. Rename that function to register_rt_signal_handler
and add a new register_signal_handler that supports all signals, then
update references to the old name.

BUG=chromium:1008990
TEST=builds

Change-Id: I455e14c562cd1f2ca4b308b4e38c503845321926
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1836185
Tested-by: Fletcher Woodruff <fletcherw@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Fletcher Woodruff <fletcherw@chromium.org>
This commit is contained in:
Fletcher Woodruff 2019-10-02 13:11:34 -06:00 committed by Commit Bot
parent f9b035d50c
commit 82ff397489
2 changed files with 24 additions and 13 deletions

View file

@ -44,10 +44,10 @@ use sys_util::net::{UnixSeqpacket, UnixSeqpacketListener, UnlinkUnixSeqpacketLis
use sys_util::{ use sys_util::{
self, block_signal, clear_signal, drop_capabilities, error, flock, get_blocked_signals, self, block_signal, clear_signal, drop_capabilities, error, flock, get_blocked_signals,
get_group_id, get_user_id, getegid, geteuid, info, register_signal_handler, set_cpu_affinity, get_group_id, get_user_id, getegid, geteuid, info, register_rt_signal_handler,
validate_raw_fd, warn, EventFd, FlockOperation, GuestAddress, GuestMemory, Killable, set_cpu_affinity, validate_raw_fd, warn, EventFd, FlockOperation, GuestAddress, GuestMemory,
MemoryMapping, PollContext, PollToken, Protection, SignalFd, Terminal, TimerFd, WatchingEvents, Killable, MemoryMapping, PollContext, PollToken, Protection, SignalFd, Terminal, TimerFd,
SIGRTMIN, WatchingEvents, SIGRTMIN,
}; };
use vhost; use vhost;
use vm_control::{ use vm_control::{
@ -1085,7 +1085,7 @@ fn setup_vcpu_signal_handler() -> Result<()> {
unsafe { unsafe {
extern "C" fn handle_signal() {} extern "C" fn handle_signal() {}
// Our signal handler does nothing and is trivially async signal safe. // Our signal handler does nothing and is trivially async signal safe.
register_signal_handler(SIGRTMIN() + 0, handle_signal) register_rt_signal_handler(SIGRTMIN() + 0, handle_signal)
.map_err(Error::RegisterSignalHandler)?; .map_err(Error::RegisterSignalHandler)?;
} }
block_signal(SIGRTMIN() + 0).map_err(Error::BlockSignal)?; block_signal(SIGRTMIN() + 0).map_err(Error::BlockSignal)?;

View file

@ -90,21 +90,15 @@ pub fn SIGRTMAX() -> c_int {
unsafe { __libc_current_sigrtmax() } unsafe { __libc_current_sigrtmax() }
} }
fn valid_signal_num(num: c_int) -> bool { fn valid_rt_signal_num(num: c_int) -> bool {
num >= SIGRTMIN() && num <= SIGRTMAX() num >= SIGRTMIN() && num <= SIGRTMAX()
} }
/// Registers `handler` as the signal handler of signum `num`. /// Registers `handler` as the signal handler of signum `num`.
/// ///
/// The value of `num` must be within [`SIGRTMIN`, `SIGRTMAX`] range.
///
/// This is considered unsafe because the given handler will be called asynchronously, interrupting /// This is considered unsafe because the given handler will be called asynchronously, interrupting
/// whatever the thread was doing and therefore must only do async-signal-safe operations. /// whatever the thread was doing and therefore must only do async-signal-safe operations.
pub unsafe fn register_signal_handler(num: c_int, handler: extern "C" fn()) -> errno::Result<()> { pub unsafe fn register_signal_handler(num: c_int, handler: extern "C" fn()) -> errno::Result<()> {
if !valid_signal_num(num) {
return Err(errno::Error::new(EINVAL));
}
let mut sigact: sigaction = mem::zeroed(); let mut sigact: sigaction = mem::zeroed();
sigact.sa_flags = SA_RESTART; sigact.sa_flags = SA_RESTART;
sigact.sa_sigaction = handler as *const () as usize; sigact.sa_sigaction = handler as *const () as usize;
@ -117,6 +111,23 @@ pub unsafe fn register_signal_handler(num: c_int, handler: extern "C" fn()) -> e
Ok(()) Ok(())
} }
/// Registers `handler` as the signal handler for the real-time signal with signum `num`.
///
/// The value of `num` must be within [`SIGRTMIN`, `SIGRTMAX`] range.
///
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
pub unsafe fn register_rt_signal_handler(
num: c_int,
handler: extern "C" fn(),
) -> errno::Result<()> {
if !valid_rt_signal_num(num) {
return Err(errno::Error::new(EINVAL));
}
register_signal_handler(num, handler)
}
/// Creates `sigset` from an array of signal numbers. /// Creates `sigset` from an array of signal numbers.
/// ///
/// This is a helper function used when we want to manipulate signals. /// This is a helper function used when we want to manipulate signals.
@ -260,7 +271,7 @@ pub unsafe trait Killable {
/// ///
/// The value of `num` must be within [`SIGRTMIN`, `SIGRTMAX`] range. /// The value of `num` must be within [`SIGRTMIN`, `SIGRTMAX`] range.
fn kill(&self, num: c_int) -> errno::Result<()> { fn kill(&self, num: c_int) -> errno::Result<()> {
if !valid_signal_num(num) { if !valid_rt_signal_num(num) {
return Err(errno::Error::new(EINVAL)); return Err(errno::Error::new(EINVAL));
} }