A signal is a mechanism for transferring control that is typically used to notify a process that an event has occurred. That process can then respond to the event accordingly. The C Standard provides functions for sending and handling signals within a C program.
Processes handle signals by registering a signal handler using the
signal() function, which is specified as
This signal handler is conceptually equivalent to
Signal handlers can be interrupted by signals, including their own. If a signal is not reset before its handler is called, the handler can interrupt its own execution. A handler that always successfully executes its code despite interrupting itself or being interrupted is async-signal-safe.
Some platforms provide the ability to mask signals while a signal handler is being processed. If a signal is masked while its own handler is processed, the handler is noninterruptible and need not be async-signal-safe. However, even when a signal is masked while its own handler is processed, the handler must still avoid invoking async-signal-safe unsafe functions because their execution may be (or have been) interrupted by another signal.
Vulnerabilities can arise if a signal handler that is not async-signal-safe is interrupted with any unmasked signal, including its own.
Noncompliant Code Example
This noncompliant code example registers a single signal handler to process both
SIGUSR2. The variable
sig2 should be set to
1 if one or more
SIGUSR1 signals are followed by
SIGUSR2, essentially implementing a finite state machine within the signal handler.
Unfortunately, a race condition occurs in the implementation of
handler() is called to handle
SIGUSR1 and is interrupted to handle
SIGUSR2, it is possible that
sig2 will not be set.
Compliant Solution (POSIX)
sigaction() function assigns handlers to signals in a similar manner to the C
signal() function, but it also allows signal masks to be set explicitly. Consequently,
sigaction() can be used to prevent a signal handler from interrupting itself.
sigaction() and deprecates the use of
signal() to register signal handlers. Unfortunately,
sigaction() is not defined in the C Standard and is consequently not as portable a solution.
Interrupting a noninterruptible signal handler can result in a variety of vulnerabilities [Zalewski 2001].
|BADFUNC.SIGNAL||Use of signal|
|LDRA tool suite|
|44 S||Enhanced enforcement|
The signal handling facilities of <signal.h> shall not be used
Assistance provided: reports use of the signal function
|SEI CERT C++ Coding Standard||VOID SIG00-CPP. Mask signals handled by noninterruptible signal handlers|
|MITRE CWE||CWE-662, Insufficient synchronization|
|[C99 Rationale 2003]||Subclause 5.2.3, "Signals and Interrupts"|
|[Dowd 2006]||Chapter 13, "Synchronization and State" ("Signal Interruption and Repetition")|
|[IEEE Std 1003.1:2013]||XSH, System Interface, |
|[Zalewski 2001]||"Delivering Signals for Fun and Profit"|