...
The result of calling malloc(0)
to allocate 0 bytes is implementation-defined. In this example, a dynamic array of integers is allocated to store size
elements. However, if size
is zero, the call to malloc(size)
may return a reference to a block of memory of size 0 rather than NULL
. When data is copied to this location, a heap-buffer overflow occurs.
Code Block | ||
---|---|---|
| ||
size_t size;
/* initialize size, possibly by user-controlled input */
int *list = malloc(size);
if (list == NULL) {
/* Handle Allocation Error */
}
/* Continue Processing list */
|
...
To ensure that zero is never passed as a size argument to malloc()
, size
is checked to ensure it has a positive value.
Code Block | ||
---|---|---|
| ||
size_t size; /* initialize size, possibly by user-controlled input */ if (size <== 0) { /* Handle Error */ } int *list = malloc(size); if (list == NULL) { /* Handle Allocation Error */ } /* Continue Processing list */ |
...
If this non-compliant code is compiled with gcc GCC 3.4.6 and linked with libc 2.3.4, invoking realloc(p, 0)
returns a non-null pointer to a zero-sized object (the same as malloc(0)
). However, if the same code is compiled with either Microsoft Visual Studio Version 7.1 or gcc GCC version 4.1.0 , realloc(p, 0)
returns a null pointer, resulting in a double-free vulnerability.
Compliant
...
Solution
This compliant solution does Do not pass a size argument of zero to the realloc()
function.
...