Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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
bgColor#FFcccc
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
bgColor#ccccff
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).

...