...
In this non-compliant code example, cBlocks num_blocks is multiplied by 16 and the result is stored in the unsigned long long int alloc.
| Code Block | ||
|---|---|---|
| ||
enum { BLOCKSIZE = 16 };
/* ... */
void * AllocBlocksalloc_blocks(size_t cBlocksnum_blocks) {
if (cBlocksnum_blocks == 0) {
return NULL;
}
unsigned long long alloc = cBlocksnum_blocks * BLOCKSIZE ;
return (alloc < UINT_MAX)
? malloc(cBlocksnum_blocks * BLOCKSIZE )
: NULL;
}
|
For example, if size_t is represented as a 32-bit unsigned value and unsigned long long represented as a 64-bit unsigned value, the result of this multiplication can still overflow because the actual multiplication is a 32-bit operation. As a result, the value stored in alloc will always be less than UINT_MAX.
...
| Code Block | ||
|---|---|---|
| ||
enum { BLOCKSIZE = 16 };
/* ... */
void *AllocBlocksalloc_blocks(size_t cBlocksnum_blocks) {
if (cBlocksnum_blocks == 0 || cBlocksnum_blocks > SIZE_MAX / BLOCKSIZE)
return NULL;
return malloc (cBlocksnum_blocks * BLOCKSIZE);
} /* end AllocBlocks */
|
This example checks the value of cBlocks num_blocks to make sure the subsequent multiplication operation cannot result in an integer overflow. The code also ensures that cBlocks num_blocks is not equal to zero (see MEM04-A. Do not perform zero length allocations).
...