...
When calloc()
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.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h>
void *p;
void func(size_t new_size) {
if (new_size == 0) {
/* Handle error */
}
p = realloc(p, new_size);
if (p == NULL) {
/* Handle error */
}
} |
This code example does comply with MEM04-C. Do not perform zero-length allocations.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h>
void *p;
void func(size_t new_size) {
void *q;
if (new_size == 0) {
/* Handle error */
}
q = realloc(p, new_size);
if (q == NULL) {
/* Handle error */
} else {
p = q;
}
} |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <string.h> extern void log_message(const char *); void f(int i, int width, int prec) { char buf[40]; int n; n = snprintf(buf, sizeof(buf), "i = %*.*i", width, prec, i); if (n < 0 || n >= sizeof(buf)) { /* Handle snprintf() error */ strcpy(buf, "unknown error"); } log_message(buf); } |
Compliant Solution (snprintf(
null)
)
When the length of the formatted string is unbounded, you can first invoke snprintf()
with a null buffer pointer to determine the size of output, then dynamically allocate a buffer of sufficient size, and finally call snprintf()
again to format the output into the dynamically allocated buffer. Even with this approach, the success of all calls still needs to be tested, and any errors still must be appropriately handled. A possible optimization is to first attempt to format the string into a reasonably small buffer allocated on the stack and, only when the buffer turns out to be too small, allocate one of a sufficient size dynamically:
...