Calling the signal()
function in a multithreaded program is undefined behavior. (See undefined behavior 135.)
Noncompliant Code Example
This noncompliant code example invokes the signal()
function from a multithreaded program:
#include <signal.h> #include <stddef.h> #include <threads.h> volatile sig_atomic_t flag = 0; void handler(int signum) { flag = 1; } /* Runs until user sends SIGUSR1 */ int func(void *data) { while (!flag) { /* ... */ } return 0; } int main(void) { signal(SIGUSR1, handler); /* Undefined behavior */ thrd_t tid; if (thrd_success != thrd_create(&tid, func, NULL)) { /* Handle error */ } /* ... */ return 0; }
NOTE: The SIGUSR1
signal value is not defined in the C Standard; consequently, this is not a C-compliant code example.
Compliant Solution
This compliant solution uses an object of type atomic_bool
to indicate when the child thread should terminate its loop:
#include <stdatomic.h> #include <stdbool.h> #include <stddef.h> #include <threads.h> atomic_bool flag = ATOMIC_VAR_INIT(false); int func(void *data) { while (!flag) { /* ... */ } return 0; } int main(void) { thrd_t tid; if (thrd_success != thrd_create(&tid, func, NULL)) { /* Handle error */ } /* ... */ /* Set flag when done */ flag = true; return 0; }
Exceptions
CON37-C-EX1: Implementations such as POSIX that provide defined behavior when multithreaded programs use custom signal handlers are exempt from this rule [IEEE Std 1003.1-2013].
Risk Assessment
Mixing signals and threads causes undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON37-C | Low | Probable | Low | P6 | L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Astrée | 24.04 | stdlib-use-signal | Fully checked |
CodeSonar | 8.1p0 | BADFUNC.SIGNAL | Use of signal |
Coverity | 2017.07 | MISRA C 2012 Rule 21.5 | Over-constraining |
Helix QAC | 2024.3 | C5021 C++5022 | |
Klocwork | 2024.3 | MISRA.STDLIB.SIGNAL | |
LDRA tool suite | 9.7.1 | 44 S | Enhanced enforcement |
Parasoft C/C++test | 2023.1 | CERT_C-CON37-a | The signal handling facilities of <signal.h> shall not be used |
PC-lint Plus | 1.4 | 586 | Fully supported |
Polyspace Bug Finder | R2024a | CERT C: Rule CON37-C | Checks for signal call in multithreaded program (rule fully covered) |
RuleChecker | 24.04 | stdlib-use-signal | Fully checked |
Bibliography
[IEEE Std 1003.1-2013] | XSH 2.9.1, "Thread Safety" |