Race Condition in Signal Handler

From Guidance Share

Jump to: navigation, search

Contents

Description

Race conditions occur frequently in signal handlers, since they are asynchronous actions. These race conditions may have any number of root-causes and symptoms.

Applies To

  • Languages: C, C++, Assembly
  • Operating platforms: All

Example

The following code demonstrates a race condition in a signal handler:

void *global1, *global2;
char *what;
void sh(int dummy) { 
printf("%s\n",what); 
if (global2!=NULL){
   free(global2); 
   global2 = NULL;
}
if (global1!=NULL){
   free(global1); 
   global1 = NULL;
}
}

int main(int argc,char* argv[]) { 
what=argv[1]; 
global1=strdup(argv[2]); 
global2=malloc(340); 
signal(SIGHUP,sh); 
signal(SIGTERM,sh); 
}

Since there is no mechanism in place to ensure the function is safely reentrant, it is possible for one of the global variables to be freed twice. Even though the pointer is set to NULL after it has been freed, a race condition still exists between the time the memory was freed and the pointer was set to NULL.

Impact

  • Authorization: An attacker may be able to use the resulting system instability or memory corruption to modify arbitrary memory or run arbitrary code.
  • Integrity: Signal race conditions often result in data corruption.

Vulnerabilities

  • Signal or event handling code is not designed to be safely reentrant.

Countermeasures

  • Requirements specification: A language might be chosen, which is not subject to this flaw, through a guarantee of safely reentrant code.
  • Design: Design signal handlers to only set flags rather than perform complex functionality.
  • Implementation: Ensure that non-reentrant functions are not found in signal handlers. Also, use sanity checks to ensure that state is consistent be performing asynchronous actions which effect the state of execution.

Vulnerability Patterns

How Tos

Personal tools