Versions Compared

Key

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

...

Similarly, Section 7.14.1.1, paragraph 5 of C99 C11 [ISO/IEC 9899:19992011], states that if the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if

...

Code Block
bgColor#FFcccc
langc

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

enum { MAXLINE = 1024 };
char *info = NULL;

void log_message(void) {
  fprintf(stderr, info);
}

void handler(int signum) {
  log_message();
  free(info);
  info = NULL;
}

int main(void) {
  if (signal(SIGINT, handler) == SIG_ERR) {
    /* Handle error */
  }
  info = (char*)malloc(MAXLINE);
  if (info == NULL) {
    /* Handle Error */
  }

  while (1) {
    /* Main loop program code */

    log_message();

    /* More program code */
  }
  return 0;
}

...

The third problem is if SIGINT occurs after the call to free(), resulting in the memory referenced by info being freed twice. This is a violation of rules MEM31-C. Free dynamically allocated memory exactly once and SIG31-C. Do not access or modify shared objects in signal handlers.

The fourth problem is that the signal handler reads the variable info, which is not declared to be of type volatile sig_atomic_t. This is a violation of rule SIG31-C. Do not access or modify shared objects in signal handlers.

...

Note that while raise() is on the list of asynchronous-safe functions, it is specifically covered by rule SIG33-C. Do not recursively invoke the raise() function.

...

Code Block
bgColor#ccccff
langc

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

enum { MAXLINE = 1024 };
volatile sig_atomic_t eflag = 0;
char *info = NULL;

void log_message(void) {
  fprintf(stderr, info);
}

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

int main(void) {
  if (signal(SIGINT, handler) == SIG_ERR) {
    /* Handle error */
  }
  info = (char*)malloc(MAXLINE);
  if (info == NULL) {
    /* Handle error */
  }

  while (!eflag) {
    /* Main loop program code */

    log_message();

    /* More program code */
  }

  log_message();
  free(info);
  info = NULL;

  return 0;
}

...

CERT C++ Secure Coding Standard: SIG30-CPP. Call only asynchronous-safe functions within signal handlers

ISO/IEC 9899:19992011 Section 7.14, "Signal handling <signal.h>"

ISO/IEC TR 17961 (Draft) Calling functions in the C Standard Library other than abort, _Exit, and signal from within a signal handler [asyncsig]

MITRE CWE: CWE ID 479, "Unsafe Function Call from a Signal Handler"

...