Versions Compared

Key

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

Accessing or modifying shared objects in signal handlers can result in race conditions that can leave data in an inconsistent state. The exception to this rule is the ability to read and write to lock-free atomic objects or variables of volatile sig_atomic_t. The need for the volatile keyword is described in DCL34 DCL22-C. Use volatile for data that cannot be cached. It is important to note that the behavior of a program that accesses an object of any other type from a signal handler is undefined. (See undefined behavior 131 in Appendix J of the C Standard.)

...

Code Block
bgColor#FFcccc
langc
#include <signal.h>
#include <stdlib.h>
#include <string.h>

char *err_msg;
enum { MAX_MSG_SIZE = 24 };

void handler(int signum) {
  strcpy(err_msg, "SIGINT encountered.");
}

int main(void) {
  signal(SIGINT, handler);

  err_msg = (char *)malloc(MAX_MSG_SIZE);
  if (err_msg == NULL) {
    /* Handle error condition. */
  }
  strcpy(err_msg, "No errors yet.");

  /* Main code loop. */

  return 0;
}

Compliant Solution

...

Code Block
bgColor#ccccff
langc
#include <signal.h>
#include <stdlib.h>
#include <string.h>

enum { MAX_MSG_SIZE = 24 };
volatile sig_atomic_t e_flag = 0;

void handler(int signum) {
  e_flag = 1;
}

int main(void) {
  char *err_msg = (char *)malloc(MAX_MSG_SIZE);
  if (err_msg == NULL) {
    /* Handle error condition. */
  }

  signal(SIGINT, handler);
  strcpy(err_msg, "No errors yet.");

  /* Main code loop. */

  if (e_flag) {
    strcpy(err_msg, "SIGINT received.");
  }
  return 0;
}

...

Code Block
bgColor#ffcccc
langc
#include <signal.h>

extern double compute_value();

static volatile double value;   /* bug: not declared sig_atomic_t */

void sigfpe_handler(int signum) {
  if (0.0 == value)   /* bug: accessing non-sig_atomic_t object */{
    value = 1.0;
  /* bug: SIGFPE handler returns */}
}

int main(void) {
  signal(SIGFPE, sigfpe_handler);
  value = compute_value();
  return 0;
}

...

CERT C++ Secure Coding StandardSIG31-CPP. Do not access shared objects in signal handlers
ISO/IEC TS 17961 (Draft)Accessing shared objects in signal handlers [accsig]
MITRE CWECWE-662, Insufficient synchronization

Bibliography

...

[ISO/IEC 2003]"Signals and Interrupts"
[Open Group 2004]longjmp
[OpenBSD]signal() Man Page
[Zalewski 2001]"Delivering Signals for Fun and Profit"

 

...