...
Different actions must be taken depending on whether or not the application requires signal handlers to be persistent.
...
Persistent Handlers
Asynchronous signals may originate from potentially hostile sources outside the process. Consequently, vulnerabilities may exist in cases where the signal handler persistence behavior is inconsistent with the developer's expectations, for example, the developer expects the signal handler to persist when it does not.
...
A secure solution would prevent the OS environment from resetting the signal in the first place, and thereby guarantee guaranteeing persistence. Unfortunately, Windows does not provide a secure solution to this problem.
...
POSIX recommends sigaction()
and deprecates signal()
. Unfortunately, sigaction()
is not defined in C99 and is consequently not as portable a solution.
Non-Persistent Handlers
Errors may also occur when the developer expects the default action to be restored for a signal, but instead, the signal handler persists.
...
Code Block | ||
---|---|---|
| ||
void handler(int signum) { #ifndef WINDOWS signal(signum, SIG_DFL); #endif /* handling code */ } |
...
There is no race condition that can be exploited by an attacker in sending a second signal, because a second signal sent to the handler before it calls signal()
will merely cause it to restart, and call signal()
anyway.
...
Code Block | ||
---|---|---|
| ||
/* Equivalent to signal( SIGUSR1, handler); */
but make signal non-persistent */
struct sigaction act;
act.sa_handler = &handler;
act.sa_flags = SA_RESETHAND;
if (sigemptyset( &act.sa_mask) != 0) {
/* handle error */
}
if (sigaction(SIGUSR1, &act, NULL) != 0) {
/* handle error */
}
|
Compliant Solution (Windows)
Windows automatically resets handlers to default.
Code Block | ||
---|---|---|
| ||
void handler(int signum) {
/* handling code */
}
|
Risk Assessment
Failure to understand implementation-specific details regarding signal handler persistence can lead to unexpected behavior.
...