...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h> volatile sig_atomic_t interrupted; void handle_interrupt(int signo) { interrupted = 1; } int f(void) { int result = 0; void (*saved_handler)(int); saved_handler = signal(SIGINT, handle_interrupt); if (SIG_ERR == (int)saved_handler) { /* Indicate failure */ return -1; } while (0 == result && 0 == interrupted) { /* Perform a lengthy computation */ } if (SIG_ERR == signal(SIGINT, saved_handler)) { return -1; } /* Indicate success or failure */ return interrupted ? -1 : result; } |
Noncompliant Code Example (
...
calloc()
)
In this noncompliant code example, temp_num
, tmp2
, and num_of_records
are derived from a tainted source. Consequently, an attacker can easily cause malloccalloc()
to fail by providing a large value for num_of_records
.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> #include <string.h> typedef struct { char sig_desc[32]; } signal_info; void func(size_t num_of_records, size_t temp_num, const char *tmp2) { signal_info *start = (signal_info *)malloccalloc(num_of_records *, sizeof(signal_info)); signal_info *point = start + temp_num - 1; if (tmp2 == NULL) { /* Handle error */ } memcpy(point->sig_desc, tmp2, strlen(tmp2)); /* ... */ } |
When malloccalloc()
fails, it returns a null pointer that is assigned to start
. If start
is a null, an attacker can provide a value for temp_num
that, when scaled by the the sizeof(signal_info)
, references a writable address to which control is eventually transferred. The contents of the string referenced by tmp2
can then be used to overwrite the address, resulting in an arbitrary code execution vulnerability.
Compliant Solution (
...
calloc()
)
To correct this error, ensure the pointer returned by malloccalloc()
is not null.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> #include <string.h> typedef struct { char sig_desc[32]; } signal_info; void func(size_t num_of_records, size_t temp_num, const char *tmp2) { signal_info *point; signal_info *start = (signal_info *)malloccalloc(num_of_records *, sizeof(signal_info)); if (start == NULL) { /* Handle allocation error */ } else if (tmp2 == NULL) { /* Handle error */ } point = start + temp_num - 1; memcpy(point->sig_desc, tmp2, strlen(tmp2)); /* ... */ } |
...