Versions Compared

Key

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

...

The compliant solution does not reference errno and does not return from the signal handler if the signal() call fails.:

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

typedef void (*pfv)(int);

void handler(int signum) {
  pfv old_handler = signal(signum, SIG_DFL);
  if (old_handler == SIG_ERR) {
    abort();
  }
}

int main(void) {
  pfv old_handler = signal(SIGINT, handler);
  if (old_handler == SIG_ERR) {
    perror("SIGINT handler");
    /* Handle error condition */
  }

  /* Main code loop */

  return EXIT_SUCCESS;
}

...

The compliant solution saves and restores the value of errno in the signal handler.:

Code Block
bgColor#ccccff
langc
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>

void reaper(int signum) {
  int save_errno = errno;
  errno = 0;
  for (;;) {
    int rc = waitpid(-1, NULL, WNOHANG);
    if ( (0 == rc) || (-1 == rc && EINTR != errno) )
      break;
  }
  if (ECHILD != errno) {
    /* Handle error */
  }
  errno = save_errno;
}

int main(void) {
  struct sigaction act;
  act.sa_handler = reaper;
  act.sa_flags = 0;
  if (sigemptyset(&act.sa_mask) != 0) {
    /* Handle error */
  }
  if (sigaction(SIGCHLD, &act, NULL) != 0) {
    /* Handle error */
  }

  /* ... */

  return EXIT_SUCCESS;
}

...

Tool

Version

Checker

Description

Compass/ROSE

 

 

Could detect violations of this rule by looking for signal handlers that themselves call signal(). A violation is reported if the call fails and the handler therefore checks errno. A violation also exists if the signal handler modifies errno without first copying its value elsewhere.

Related Vulnerabilities

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

...