...
Code Block | ||||
---|---|---|---|---|
| ||||
size_t size; /* Initialize size, possibly by user-controlled input */ int *list = (int *)malloc(size); if (list == NULL) { /* Handle allocation error */ } else { /* Continue processing list */ } |
Compliant Solution (malloc()
)
To ensure that 0 is never passed as a size argument to malloc()
, size
is checked to confirm it has a positive value:
Code Block | ||||
---|---|---|---|---|
| ||||
size_t size; /* Initialize size, possibly by user-controlled input */ if (size == 0) { /* Handle error */ } int *list = (int *)malloc(size); if (list == NULL) { /* Handle allocation error */ } /* Continue processing list */ |
Noncompliant Code Example (realloc()
)
The realloc()
function deallocates the old object and returns a pointer to a new object of a specified size. If memory for the new object cannot be allocated, the realloc()
function does not deallocate the old object, and its value is unchanged. If the realloc()
function returns NULL
, failing to free the original memory will result in a memory leak. As a result, the following idiom is often recommended for reallocating memory:
...
If this noncompliant code is compiled with 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 or GCC 4.1.0 , realloc(p, 0)
returns a null pointer, resulting in a double-free vulnerability.
Compliant Solution (realloc()
)
This compliant solution does not pass a size argument of zero to the realloc()
function:
...