...
The following noncompliant code example defines A
to be a variable length array type and then uses the sizeof
operator to compute its size at runtime. When the function is called with an argument greater than SIZE_MAX / (N N1 * n2 * sizeof (int)
), the runtime sizeof
expression may wrap around, yielding a result that is smaller than the mathematical product N N1 * n n2 * sizeof (int)
. The call to malloc()
, when successful, will then allocate storage for fewer than n
n2
elements of the array, causing one of the final memset()
calls in the for
loop to write past the end of that storage.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> #include <string.h> enum { NN1 = 4096 }; void* func(size_t nn2) { typedef int A [nn2][NN1]; A *array = malloc(sizeof (A)); for (size_t i = 0; i != nn2; ++i) memset(array [i], 0, NN1 * sizeof (int)); return array; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> #include <string.h> enum { NN1 = 4096 }; void* func(size_t nn2) { if (nn2 > SIZE_MAX / (NN1 * sizeof (int))) { /* Prevent sizeof wrapping */ return NULL; } typedef int A [nn2][NN1]; A *array = malloc(sizeof (A)); if (array == NULL) { /* Handle malloc failure */ return NULL; } for (size_t i = 0; i != nn2; ++i) memset( array [i], 0, NN1 * sizeof (int)); return array; } |
...