Accessing or modifying shared objects in signal handlers can result in race conditions that can leave data in an inconsistent state. The two exceptions (C Standard, 5.1.2.3, paragraph 5) to this rule are the ability to read from and write to lock-free atomic objects or to read from or write to and variables of type volatile sig_atomic_t. Accessing any other type of object from a signal handler is undefined behavior. (see See undefined behavior 131.).
The need for the volatile keyword is described in DCL22-C. Use volatile for data that cannot be cached.
...
The signal handler may also call a handful of functions, including abort(). (see See SIG30-C. Call only asynchronous-safe functions within signal handlers for more information.).
Noncompliant Code Example
...
Signal handlers can refer to objects with static or thread storage duration durations that are lock-free atomic objects, as in this compliant solution:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <signal.h> #include <stdlib.h> #include <string.h> #include <stdatomic.h> #if#ifdef __STDC_NO_ATOMICS__ == 1 #error "Atomics isare not supported" #elif ATOMIC_INT_LOCK_FREE == 0 #error "int is never lock-free" #endif atomic_int e_flag = ATOMIC_VAR_INIT(0); void handler(int signum) { eflage_flag = 1; } int main(void) { enum { MAX_MSG_SIZE = 24 }; char err_msg[MAX_MSG_SIZE]; #if ATOMIC_INT_LOCK_FREE == 1 if (!atomic_is_lock_free(&e_flag)) { return EXIT_FAILURE; } #endif if (signal(SIGINT, handler) == SIG_ERR) { return EXIT_FAILURE; } strcpy(err_msg, "No errors yet."); /* Main code loop */ if (e_flag) { strcpy(err_msg, "SIGINT received."); } return EXIT_SUCCESS; } |
Exceptions
SIG31-C-EX1: The C Standard, 7.14.1.1 paragraph 5 [ISO/IEC 9899:20112024], makes a special exception for errno when a valid call to the signal() function results in a SIG_ERR return, allowing errno to take an indeterminate value. (see See ERR32-C. Do not rely on indeterminate values of errno.)
the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler. Furthermore, if such a call to the signal function results in a SIG_ERR return, the object designated by errno has an indeterminate representation.
Risk Assessment
Accessing or modifying shared objects in signal handlers can result in accessing data in an inconsistent state. Michal Zalewski's paper "Delivering Signals for Fun and Profit" [Zalewski 2001] provides some examples of vulnerabilities that can result from violating this and other signal-handling rules.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|---|---|
SIG31-C | High | Likely |
Yes | No |
P18 |
L1 |
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| signal-handler-shared-access | Partially checked | ||||||
| Axivion Bauhaus Suite |
| CertC-SIG31 | |||||||
| CodeSonar |
| CONCURRENCY.DATARACE | Data |
| race |
| Compass/ROSE |
Can detect violations of this rule for single-file programs | |||||||||
| Cppcheck Premium | 24.9.0 | premium-cert-sig31-c | |||||||
| Helix QAC |
| C2029, C2030 C++3854, C++3855 | |||||||
| LDRA tool suite |
| 87 D | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_C-SIG31-a | Properly define signal handlers | ||||||
| PC-lint Plus |
| 2765 | Fully supported | ||||||
| CERT C: Rule SIG31-C | Checks for shared data access within signal handler (rule partially covered) | |||||||
| RuleChecker |
| signal-handler-shared-access | Partially checked |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
|---|
| ISO/IEC TS 17961:2013 | Accessing shared objects in signal handlers [accsig] | Prior to 2018-01-12: CERT: Unspecified Relationship |
| CWE 2.11 | CWE-662, Improper Synchronization | 2017-07-10: CERT: Rule subset of CWE |
| CWE 2.11 | CWE-828, Signal Handler with Functionality that is not Asynchronous-Safe | 2017-10-30:MITRE:Unspecified Relationship 2018-10-19:CERT:Rule subset of CWE |
CERT-CWE Mapping Notes
Key here for mapping notes
CWE-662 and SIG31-C
CWE-662 = Union( SIG31-C,
...
list) where list =
- Improper synchronization of shared objects between threads
- Improper synchronization of files between programs (enabling TOCTOU race conditions
CWE-828 and SIG31-C
CWE-828 = SIG31-C + non-async-safe things besides shared objects.
Bibliography
| [C99 Rationale 2003] | 5.2.3, "Signals and Interrupts" |
| [ISO/IEC 9899: |
| 2024] | Subclause 7.14.1.1, "The signal Function" |
| [Zalewski 2001] |
...
...