Versions Compared

Key

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

Signal handlers can be interrupted by signals, including their own signals. If a signal is not reset before its handler is called, the handler can interrupt its own execution. A handler that always successfully executes its code despite interrupting itself is said to be re-entrantasynchronous-safe.

Some platforms provide the ability to mask signals while a signal handler is being processed. If a signal is masked while its own handler is processed, the handler is un-interruptible, and need not be reasynchronous-entrantsafe.

Vulnerabilities can arise if a non-reasynchronous-entrant safe signal handler is interrupted with its own signal, especially if it manipulates globally-accessible data.

...

This non-compliant code example moves the finite state machine out of the signal handler, making the handler reasynchronous-entrantsafe.

Code Block
bgColor#ccccff
#include <signal.h>

volatile sig_atomic_t sig1 = 0;
volatile sig_atomic_t sig2 = 0;

void handler(int signum) {
  if (signum == SIGUSR1) {
    sig1 = 1;
  }
  else if (signum == SIGUSR2) {
    sig2 = 1;
  }
}

int main(void) {
  int state = 0;
  signal(SIGUSR1, handler);
  signal(SIGUSR2, handler);

  while (state != 2) {
    /* do nothing or give up CPU for a while */
    if (state == 0 && sig1) {
      state = 1;
      sig2 = 0;
    }
    if (state == 1 && sig2) {
      state = 2;
    }
  }

  /* ... */

  return 0;
}

...