...
If the signal occurs as the result of calling the
abortorraisefunction, the signal handler shall not call theraisefunction.
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.
...