CertC-CON37¶
Do not call signal() in a multithreaded program
Required inputs: IR
This Cert Rule assumes that the software under analysis is multithreaded. If this is not the case, the rule can be disabled!
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 |
Bibliography
| [ IEEE Std 1003.1-2013] | XSH 2.9.1, "Thread Safety" |
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
forbidden_libfunc_call |
Do not call signal() in a multithreaded program. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
blacklist¶
blacklist
Dictionary of header globbing to (list of) function name globbing(s) of forbidden functions.Type: dict[bauhaus.analysis.config.FileGlobPattern, list[bauhaus.analysis.config.GlobPattern]]
Default:
{ 'signal.h': ['signal'] }