Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ffcccc
langc
#include <signal.h>
 
void handler(int signum) {
  if (signal(signum, handler) == SIG_ERR) {
    /* Handle error */
  }
  /* Handle signal */
}
/* ... */
 
void func(void) {
  if (signal(SIGUSR1, handler) == SIG_ERR) {
    /* Handle error */
  }
}

On nonpersistent platforms, this solution contains a race window, starting when the host environment resets the signal and ending when the handler calls signal(). During that time, a second signal sent to the program will trigger the default signal behavior, consequently defeating the persistent behavior implied by the call to signal() from within the handler to reassert the binding.

...

Code Block
bgColor#ccccff
langc
#include <signal.h>
 
void handler(int signum) {
  /* Handle signal */
}
/* ... */
 
void func(void) {
  if (signal(SIGUSR1, handler) == SIG_ERR) {
    /* Handle error */
  }
}

Compliant Solution (POSIX)

...

Code Block
bgColor#ccccff
langc
#include <signal.h>
 
void handler(int signum) {
  /* Handle signal */
}

/* ... */

void func(void) {
  struct sigaction act;
  act.sa_handler = handler;
  act.sa_flags = 0;
  if (sigemptyset( &act.sa_mask) != 0) {
    /* Handle error */
  }
  if (sigaction(SIGUSR1, &act, NULL) != 0) {
    /* Handle error */
  }
}

Although the handler in this example does not call signal(), it could do so safely because the signal is masked, and the handler cannot be interrupted. If the same handler is installed for more than one signal number, the signals must be masked explicitly in act.sa_mask to ensure that the handler cannot be interrupted because the system masks only the signal being delivered.

...

Code Block
bgColor#ccccff
langc
#include <signal.h>
 
void handler(int signum) {
#ifndef WINDOWS#if !defined(_WIN32)
  if (signal(signum, SIG_DFL) == SIG_ERR) {
    /* Handle error */
  }
#endif
  /* Handle signal */
}
/* ... */
 
void func(void) {
  if (signal(SIGUSR1, handler) == SIG_ERR) {
    /* Handle error */
  }
}

Risk Assessment

Two signals in quick succession can trigger the race condition on nonpersistent platforms, causing the signal's default behavior despite a handler's attempt to override it.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

SIG34-C

low

unlikely

low

P3

L3

Automated Detection

...

Tool

Version

Checker

Description

Compass/ROSE  Can detect violations of this rule. However, false positives may occur on systems with persistent handlers
PRQA QA-C
Include Page
PRQA_V
PRQA_V
Warncall -wc signalPartially implemented

...

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

...