...
Code Block |
---|
|
#include <stddef.h>
extern void do_work(int *array, size_t size);
void func(size_t size) {
int vla[size];
/* ... */do_work(vla, size);
}
|
However, the value of size
may be zero or excessive, potentially giving rise to a security vulnerability.
...
Code Block |
---|
|
#include <stdint.h>
#include <stdlib.h>
enum { MAX_ARRAY = 1024 };
extern void do_work(int *array, size_t size);
void func(size_t size) {
if (0 == size || SIZE_MAX / sizeof(int) < size) {
/* Handle error */
return;
}
if (size < MAX_ARRAY) {
int vla[size];
do_work(vla, size);
} else {
int *array = (int *)malloc(size * sizeof(int));
if (array == NULL) {
/* Handle error */
}
do_work(array, size);
free(array);
}
}
|
Noncompliant Code Example (sizeof
)
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 * sizeof (int)
), the runtime sizeof
expression may wrap around, yielding a result that is smaller than the mathematical product N * n * sizeof (int)
. The call to malloc, when successful, will then allocate storage for fewer than n
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 { N = 4096 };
void* func(size_t n) {
typedef int A [n][N];
A *array = malloc(sizeof (A));
for (size_t i = 0; i != n; ++i)
memset(array [i], 0, N * sizeof (int));
return array;
}
|
Compliant Code Solution (sizeof
)
This compliant solution prevents sizeof
wrapping by detecting the condition before it occurs and avoiding the subsequent computation when the condition is detected.
Code Block |
---|
|
#include <stdlib.h>
#include <string.h>
enum { N = 4096 };
void* func(size_t n) {
if (n > SIZE_MAX / (N * sizeof (int))) {
/* Prevent sizeof wrapping */
return NULL;
}
typedef int A [n][N];
A *array = malloc(sizeof (A));
if (array == NULL) {
/* Handle malloc failure */
return NULL;
}
for (size_t i = 0; i != n; ++i)
memset(array [i], 0, N * sizeof (int));
return array;
}
|
Implementation Details
Microsoft
...