...
If the signal occurs as the result of calling the
abort
orraise
function, the signal handler shall not call theraise
function.
However, in the description of signal()
, POSIX states:
This restriction does not apply to POSIX applications, as POSIX.1-2008 requires
raise()
to be async-signal-safe
See also undefined behavior 131.
...
The OpenBSD signal()
manual page lists a few additional functions that are asynchronous-safe in OpenBSD but "probably not on other systems," including snprintf()
, vsnprintf()
, and syslog_r()
(but only when the syslog_data struct
is initialized as a local variable).
Compliant Solution (POSIX)
In this compliant solution, the signal handlers are installed using sigaction()
, and so it is safe to use raise()
within the signal handler:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h>
void log_msg(int signum) {
/* Log error message in some asynchronous-safe manner */
}
void handler(int signum) {
/* Do some handling specific to SIGINT */
if (raise(SIGUSR1) != 0) {
/* Handle error */
}
}
int main(void) {
struct sigaction act;
act.sa_flags = 0;
if (sigemptyset(&act.sa_mask) != 0) {
/* Handle error */
}
act.sa_handler = log_msg;
if (sigaction(SIGUSR1, &act, NULL) != 0) {
/* Handle error */
}
act.sa_handler = handler;
if (sigaction(SIGINT, &act, NULL) != 0) {
/* Handle error */
}
/* Program code */
if (raise(SIGINT) != 0) {
/* Handle error */
}
/* More code */
return 0;
}
|
POSIX recommends sigaction()
and deprecates signal()
. Unfortunately, sigaction()
is not defined in the C Standard and is consequently not as portable a solution.
Risk Assessment
Invoking functions that are not asynchronous-safe from within a signal handler may result in privilege escalation and other attacks.
...