Skip to content

Commit 65dc516

Browse files
author
Alexandra Iordache
committed
sys_util: generic register_signal_handler
Renamed register_sigsys_handler to register_signal_handler, enabling the installation of custom signal handlers for any signal. Signed-off-by: Alexandra Iordache <[email protected]>
1 parent 8aefa72 commit 65dc516

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

sys_util/src/signal.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use super::SyscallReturnCode;
99
use libc::{
1010
c_int, c_void, pthread_kill, pthread_t, sigaction, sigfillset, siginfo_t, sigset_t, EINVAL,
11+
SIGHUP, SIGSYS,
1112
};
1213
use std::io;
1314
use std::mem;
@@ -36,12 +37,12 @@ fn SIGRTMAX() -> c_int {
3637
unsafe { __libc_current_sigrtmax() }
3738
}
3839

39-
/// Verifies that a signal number is valid.
40+
/// Verifies that a signal number is valid when sent to a vCPU.
4041
///
4142
/// VCPU signals need to have values enclosed within the OS limits for realtime signals.
4243
///
4344
/// Will return Ok(num) or Err(EINVAL).
44-
pub fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
45+
fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
4546
let actual_num = num + SIGRTMIN();
4647
if actual_num <= SIGRTMAX() {
4748
Ok(actual_num)
@@ -50,25 +51,42 @@ pub fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
5051
}
5152
}
5253

53-
/// Registers `handler` as the vCPU's signal handler of signum `num`.
54+
/// Verifies that a signal number is valid when sent to the process.
55+
///
56+
/// Signals can take values between `SIGHUB` and `SIGSYS`.
57+
///
58+
/// Will return Ok(num) or Err(EINVAL).
59+
fn validate_signal_num(num: c_int) -> io::Result<c_int> {
60+
if num >= SIGHUP && num <= SIGSYS {
61+
Ok(num)
62+
} else {
63+
Err(io::Error::from_raw_os_error(EINVAL))
64+
}
65+
}
66+
67+
/// Registers `handler` as the vCPU's signal handler of `signum`.
5468
///
5569
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
5670
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
57-
pub unsafe fn register_vcpu_signal_handler(num: i32, handler: SignalHandler) -> io::Result<()> {
58-
let num = validate_vcpu_signal_num(num)?;
71+
pub unsafe fn register_vcpu_signal_handler(
72+
signum: c_int,
73+
handler: SignalHandler,
74+
) -> io::Result<()> {
75+
let num = validate_vcpu_signal_num(signum)?;
5976
// Safe, because this is a POD struct.
6077
let mut sigact: sigaction = mem::zeroed();
6178
sigact.sa_flags = libc::SA_SIGINFO;
6279
sigact.sa_sigaction = handler as usize;
6380
SyscallReturnCode(sigaction(num, &sigact, null_mut())).into_empty_result()
6481
}
6582

66-
/// Registers the specified signal handler for `SIGSYS`.
67-
pub fn register_sigsys_handler(sigsys_handler: SignalHandler) -> Result<(), io::Error> {
83+
/// Registers `handler` as the process' signal handler of `signum`.
84+
pub fn register_signal_handler(signum: c_int, handler: SignalHandler) -> Result<(), io::Error> {
85+
let num = validate_signal_num(signum)?;
6886
// Safe, because this is a POD struct.
6987
let mut sigact: sigaction = unsafe { mem::zeroed() };
7088
sigact.sa_flags = libc::SA_SIGINFO;
71-
sigact.sa_sigaction = sigsys_handler as usize;
89+
sigact.sa_sigaction = handler as usize;
7290

7391
// We set all the bits of sa_mask, so all signals are blocked on the current thread while the
7492
// SIGSYS handler is executing. Safe because the parameter is valid and we check the return
@@ -78,7 +96,7 @@ pub fn register_sigsys_handler(sigsys_handler: SignalHandler) -> Result<(), io::
7896
}
7997

8098
// Safe because the parameters are valid and we check the return value.
81-
unsafe { SyscallReturnCode(sigaction(libc::SIGSYS, &sigact, null_mut())).into_empty_result() }
99+
unsafe { SyscallReturnCode(sigaction(num, &sigact, null_mut())).into_empty_result() }
82100
}
83101

84102
/// Trait for threads that can be signalled via `pthread_kill`.
@@ -116,6 +134,8 @@ mod tests {
116134
use std::thread;
117135
use std::time::Duration;
118136

137+
use libc::SIGSYS;
138+
119139
static mut SIGNAL_HANDLER_CALLED: bool = false;
120140

121141
extern "C" fn handle_signal(_: c_int, _: *mut siginfo_t, _: *mut c_void) {
@@ -130,7 +150,8 @@ mod tests {
130150
// testing bad value
131151
assert!(register_vcpu_signal_handler(SIGRTMAX(), handle_signal).is_err());
132152
assert!(register_vcpu_signal_handler(0, handle_signal).is_ok());
133-
assert!(register_sigsys_handler(handle_signal).is_ok());
153+
assert!(register_signal_handler(SIGSYS, handle_signal).is_ok());
154+
assert!(register_signal_handler(SIGSYS + 1, handle_signal).is_err());
134155
}
135156
}
136157

vmm/src/signal_handler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::result::Result;
1010
use libc::{_exit, c_int, c_void, siginfo_t, SIGSYS};
1111

1212
use logger::{Metric, LOGGER, METRICS};
13-
use sys_util::register_sigsys_handler;
13+
use sys_util::register_signal_handler;
1414

1515
// The offset of `si_syscall` (offending syscall identifier) within the siginfo structure
1616
// expressed as an `(u)int*`.
@@ -58,7 +58,7 @@ extern "C" fn sigsys_handler(num: c_int, info: *mut siginfo_t, _unused: *mut c_v
5858
/// Custom handlers are installed for: `SIGSYS`.
5959
///
6060
pub fn register_signal_handlers() -> Result<(), io::Error> {
61-
register_sigsys_handler(sigsys_handler)
61+
register_signal_handler(SIGSYS, sigsys_handler)
6262
}
6363

6464
#[cfg(test)]

0 commit comments

Comments
 (0)