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"
Excerpt from SEI CERT C++ Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/concurrency-con/con37-c], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

forbidden_libfunc_call

Do not call signal() in a multithreaded program.

None

False

Options

blacklist

blacklist

Type: dict[bauhaus.analysis.config.FileGlobPattern, list[bauhaus.analysis.config.GlobPattern]]

Default:

{
   'signal.h': ['signal']
}
Dictionary of header globbing to (list of) function name globbing(s) of forbidden functions.