You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Accessing or modifying shared objects in signal handlers can lead to race conditions, opening up security holes.

According to the "Signals and Interrupts" section of the C99 Rationale:

The C89 Committee concluded that about the only thing a strictly conforming program can do in a signal handler is to assign a value to a volatile static variable which can be written uninterruptedly and promptly return.

Non-Compliant Code Example

err_msg is updated to reflect the SIGINT signal that was encountered. Issues will occur if a SIGINT is generated prior to the malloc of err_msg finishing.

#include <signal.h> 
#include <stdlib.h>
#include <string.h>
 
char *err_msg; 
 
void handler() { 
  strcpy(err_msg, "SIGINT encountered.");
} 
 
int main() { 
  signal(SIGINT, handler); 

  err_msg = malloc(24);
  strcpy(err_msg, "No errors yet.");
 
  /* main code loop */

  return 0;
}

Compliant Solution

Signal handlers should only unconditionally set and flag, and then return.

#include <signal.h> 
#include <stdlib.h>
#include <string.h>
 
char *err_msg; 
volatile sig_atomic_t e_flag = 0;
 
void handler() { 
  e_flag = 1;
} 
 
int main() { 
  signal(SIGINT, handler); 

  err_msg = malloc(24);
  strcpy(err_msg, "No errors yet.");
 
  /* main code loop */
  if(e_flag)
    strcpy(err_msg, "SIGINT received.");


  return 0;
}

Risk Assessment

Depending on the code, this could lead to any number of attacks, many of which could give root access. For an overview of some software vulnerabilities, see [[Zalewski 06]].

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SIG31-C

3 (high)

3 (likely)

1 (high)

P9

L2

References

[[Dowd 06]] Chapter 13, Synchronization and State
[[ISO/IEC 03]] "Signals and Interrupts"
[[Open Group 04]] longjmp
[OpenBSD] signal() Man Page
[Zalewski] http://lcamtuf.coredump.cx/signals.txt

  • No labels