Calling the signal() function in a multithreaded program is undefined behavior, according to the C Standard. (See also undefined behavior 135 of Annex J.)
This rule is a specific instance of SIG02-C. Avoid using signals to implement normal functionality.
This noncompliant code example invokes the signal() function from a multithreaded program.
#include <signal.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! */
thrd_t tid;
if (thrd_success != thrd_create(&tid, func, NULL)) {
/* Handle error */
}
/* ... */
return 0;
} |
This compliant solution uses an object of type atomic_flag to indicate when the child thread should terminate its loop.
#include <stdatomic.h>
#include <threads.h>
atomic_flag flag = ATOMIC_VAR_INIT(0);
int func(void *data) {
while (!flag) {
/* ... */
}
return 0;
}
int main(void) {
int result;
thrd_t tid;
if (thrd_success != thrd_create(&tid, func, NULL)) {
/* Handle error */
}
/* ... */
/* Set flag when done */
while (!atomic_flag_test_and_set(&flag))
; /* Continue attempts */
return 0;
} |
CON37-EX1: Platforms that provide defined behavior when multithreaded programs use custom signal handlers are exempt from this rule. This exception includes POSIX, for example.
Risk Assessment
Mixing signals and threads causes undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
CON37-C | Low | Probable | Low | P6 | L2 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.