...
Noncompliant Code Example
In the following this noncompliant code example, length
is a user-supplied argument that is used to determine the length of table
.
Code Block | ||
---|---|---|
| ||
int create_table(size_t length) { char **table; if (sizeof(char *) > SIZE_MAX/length) { /* handle overflow */ return -1; } size_t table_length = length * sizeof(char *); table = (char **)malloc(table_length); if (table == NULL) { /* Handle error condition */ return -1; } /* ... */ return 0; } |
Because length
is user controlled, the value can result in a large block of memory being allocated or can cause the call to malloc()
to fail. Depending on how error handling is implemented, this may result in a denial of service or other error. A length
of zero results in a division by zero in the overflow check, which can also result in a denial of service (see INT33-C. Ensure that division and modulo operations do not result in divide-by-zero errors).
...
Code Block | ||
---|---|---|
| ||
enum { MAX_TABLE_LENGTH = 256 }; int create_table(size_t length) { size_t table_length; char **table; if (length == 0 || length > MAX_TABLE_LENGTH) { /* Handle invalid length */ return -1; } /* * The wrap check has been omitted based on the assumption * that MAX_TABLE_LENGTH * sizeof(char *) cannot exceed * SIZE_MAX. If this assumption is not valid, a check must * be added. */ assert(length <= SIZE_MAX/sizeof(char *)); table_length = length * sizeof(char *); table = (char **)malloc(table_length); if (table == NULL) { /* Handle error condition */ return -1; } /* ... */ return 0; } |
The test for length == 0
ensures that a non-zero nonzero number of bytes is allocated (see MEM04-C. Do not perform zero length allocations).
...