Call only only asynchronous-safe functions within signal handlers. For strictly conforming programs, only the C Standard Library functions abort()
, _Exit()
, and signal()
can be called from within a signal handler in the C Standard Libraryhandler.
Section 7.14.1.1, para. 5, of the C standard [ISO/IEC 9899:2011], 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 | ||||
---|---|---|---|---|
| ||||
#include <signal.h> #include <stdio.h> #include <stdlib.h> enum { MAXLINE = 1024 }; char *info = NULL; void log_message(void) { fprintf(stderr, info); /* violation */ } void handler(int signum) { log_message(); free(info); /* violation */ 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; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
enum { MAXLINE = 1024 };
static jmp_buf env;
void handler(int signum) {
longjmp(env, 1); /* violation */
}
void log_message(char *info1, char *info2) {
static char *buf = NULL;
static size_t bufsize;
char buf0[MAXLINE];
if (buf == NULL) {
buf = buf0;
bufsize = sizeof(buf0);
}
/*
* Try to fit a message into buf, else re-allocate
* it on the heap and then log the message.
*/
/*** VULNERABILITY IF SIGINT RAISED HERE ***/
if (buf == buf0) {
buf = NULL;
}
}
int main(void) {
if (signal(SIGINT, handler) == SIG_ERR) {
/* Handle error */
}
char *info1;
char *info2;
/* info1 and info2 are set by user input here */
if (setjmp(env) == 0) {
while (1) {
/* Main loop program code */
log_message(info1, info2);
/* More program code */
}
}
else {
log_message(info1, info2);
}
return 0;
}
|
...