...
Many UNIX (and UNIX-like) systems automatically reinstall signal handlers upon handler execution, meaning that the signal handler defined by the user is left in place until it is explicitly removed. For example, when this code is compiled with GCC 3.4.4 and executed under Red Hat Linux, SIGINT
is captured both times by handler
.:
Code Block |
---|
% ./test ^C Escaped from first while () ^C Escaped from second while () % |
When a signal handler is installed with the signal()
function in Windows and some UNIX systems, the default action is restored for that signal after the signal is triggered. This means that signal handlers are not automatically reinstalled. For example, when this code is compiled with Microsoft Visual Studio 2005, version 8.0, only the first SIGINT
is captured by handler
.:
Code Block |
---|
> test.exe ^C Escaped from first while () ^C > |
...
Asynchronous signals may originate from malicious actors external to the process. Consequently, vulnerabilities may exist if the signal-handler-persistence behavior is inconsistent with the developer's expectations, such as when the developer expects the signal handler to persist but it does not.
...
This noncompliant code example fails to persist the signal handler on Windows platforms and on those UNIX systems where handlers are not persistent by default.:
Code Block | ||||
---|---|---|---|---|
| ||||
void handler(int signum) { /* Handle signal */ } |
...
A common approach to create persistent signal handlers is to call signal()
from within the handler itself, consequently , unresetting the reset signal.:
Code Block | ||||
---|---|---|---|---|
| ||||
void handler(int signum) { if (signal(signum, handler) == SIG_ERR) { /* Handle error */ } /* Handle signal */ } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* * Equivalent to signal(SIGUSR1, handler) but makes * signal persistent. */ struct sigaction act; act.sa_handler = handler; act.sa_flags = 0; if (sigemptyset(&act.sa_mask) != 0) { /* Handle error */ } if (sigaction(SIGUSR1, &act, NULL) != 0) { /* Handle error */ } |
POSIX recommends sigaction()
and deprecates signal()
. Unfortunately, sigaction()
is not defined in the C standard and Standard and is consequently not as portable a solution.
...
This noncompliant code example fails to reset the signal handler to its default behavior on systems where handlers are persistent by default.:
Code Block | ||||
---|---|---|---|---|
| ||||
void handler(int signum) { /* Handle signal */ } |
...
With the compliant solution for UNIX, no race condition occurs that can be exploited by an attacker sending a second signal. This is because a second signal sent to the handler, before the latter calls signal(signum, SIG_DFL)
, will only cause the handler to restart and call signal()
anyway.
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* * Equivalent to signal(SIGUSR1, handler) but makes * signal nonpersistent . */ 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 */ } |
...
Failure to understand implementation-specific details regarding signal-handler persistence can lead to unexpected behavior.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
SIG01-C |
Low |
Unlikely |
Low | P3 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| BADFUNC.SIGNAL | Use of signal | ||||||
Compass/ROSE |
Could detect possible violations by flagging any signal handler that calls | |||||||||
Helix QAC |
| C5020 | |||||||
LDRA tool suite |
| 97 D | Partially implemented | ||||||
Parasoft C/C++test |
| CERT_C-SIG01-a | The signal handling facilities of <signal. |
h> shall not be used | ||
PC-lint Plus |
|
|
|
586 | Assistance provided: reports use of the signal function |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
...
...
...
ISO/IEC 9899:2011 Section 7.14.1.1, "The signal
function"
...
...