The result of calling malloc(0) or calloc() to allocate 0 bytes (calloc(1,0), calloc(0,0), or calloc(0,1)) is undefined. From a practical standpoint, allocating 0 bytes with calloc() and malloc() can lead to programming errors with critical security implications, such as buffer overflows. This occurs because the result of allocating 0 bytes with calloc() and malloc() may not considered an error, thus the pointer returned may not be NULL. Instead, the pointer may reference a block of memory on the heap of size zero. If memory is fetched from, or stored in this a location serious error could occur.
Non-compliant Code Example 1
In this example, the user defined function calc_size() (not shown) is used to calculate the size of the string other_srting. The result of calc_size() is returned to str_size and used as the size parameter in a call to malloc(). However, if calc_size returned zero, then when the strncpy() is executed, a heap buffer overflow will occur.
int main(int argc, char *argv[]) {
char *str = NULL;
if (argc != 2) {
/* Handle Arguments Error */
}
str = malloc(strlen(argv[1])+1);
if (str == NULL) {
/* Handle Allocation Error */
}
strcpy(str, argv[1]);
/* Process str */
return 0;
}
Compliant Code Example 1
To assure that zero is never passed as a size argument to malloc(), a check must be made on the size parameter.
int main(int argc, char *argv[]) {
char *str = NULL;
size_t size;
if (argc != 2) {
/* Handle Arguments Error */
}
size = strlen(argv[1])+1;
if (size == 0) {
/* Handle Error */
}
str = malloc(size);
if (str == NULL) {
/* Handle Allocation Error */
}
strcpy(str, argv[1]);
/* Process str */
return 0;
}
References
- Seacord 05 Chapter 4 Dynamic Memory Management