...
This non-compliant code example invokes the longjmp
free
function to transfer control from within the signal handler int_ handler() back into main()
. Once control returns to main()
, a potentially non-reentrant system call is made to strcpy(). Using the longjmp
function inside a signal handler is particularly dangerous, as it could call any part of your code. If an interrupt signal is received during or after the free
call in main, the heap will be corrupted.
Code Block | ||
---|---|---|
| ||
#include <setjmp<signal.h> #include <signal.h> static jmp_buf env;char *foo; void int_handler() { longjmp(env, 1free(foo); return_exit(0); } int main(void) { foo char *foo= malloc(15); signal(SIGINT, int_handler); if (setjmp(env) == 0) { foo = malloc(15); strcpy(foo, "NothingHello yetWorld."); } else { strcpy(foo, "Signal caught."); } /* main loop which displays foo */ puts(foo); free(foo); return 0; } |
Compliant Solution
Signal handlers should be as minimal as possible, only unconditionally setting a flag where appropriate, and returning. You may also call the _exit
function to immediately terminate program execution.
Code Block | ||
---|---|---|
| ||
#include <signal.h> int interrupted = 0; void int_handler() { interrupted = 1; return_exit(0); } int main(void) { char *foo; signal(SIGINT, int_handler); foo = malloc(15); strcpy(foo, "Nothing yet."); /* main loop which displays foo */ if (interrupted == 1) { strcpy(foo, "Signal caught."); } return 0; } |
...