Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added reference to CVE-2009-0587

...

In this noncompliant code example, num_blocks is multiplied by 16 and the result is stored in the alloc.

Code Block
bgColor#FFcccc

enum { BLOCKSIZE = 16 };
/* ... */
void *alloc_blocks(size_t num_blocks) {
  if (num_blocks == 0) {
    return NULL;
  }
  unsigned long long alloc = num_blocks * BLOCKSIZE ;
  return (alloc < UINT_MAX)
     ? malloc(num_blocks * BLOCKSIZE )
     : NULL;
}

...

In this compliant solution, the integer values passed as size arguments to memory allocation functions are of the correct size and have not been altered due to integer overflow (INT32-C. Ensure that operations on signed integers do not result in overflow) or truncation (INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data).

Code Block
bgColor#ccccff

enum { BLOCKSIZE = 16 };
/* ... */
void *alloc_blocks(size_t num_blocks) {
  if (num_blocks == 0 || num_blocks > SIZE_MAX / BLOCKSIZE)
    return NULL;
  return malloc(num_blocks * BLOCKSIZE);
}

...

In this noncompliant code example, the string referenced by str and the string length represented by len originate from untrusted sources. The length is used to perform a memcpy() into the fixed-size static array buf. The len variable is guaranteed to be less than BUFF_SIZE. However, because len is declared as an int, it can have a negative value that would bypass the check. The memcpy() function implicitly converts len to an unsigned size_t type, and the resulting operation results in a buffer overflow.

Code Block
bgColor#FFcccc

int len;
char *str;
char buf[BUFF_SIZE];

/* ... */
if (len < BUFF_SIZE){
  memcpy(buf, str, len);
}
/* ... */

...

In this compliant solution, len is declared as a size_t so there is no possibility of this variable having a negative value and bypassing the range check.

Code Block
bgColor#ccccff

size_t len;
char *str;
char buf[BUFF_SIZE];

/* ... */
if (len < BUFF_SIZE){
  memcpy(buf, str, len);
}
/* ... */

...

In this noncompliant code example, an array of long is allocated and assigned to p. However, sizeof(int) is used to size the allocated memory. If sizeof(long) is larger than sizeof(int) then an insufficient amount of memory is allocated.

Code Block
bgColor#FFcccc

void function(size_t len) {
   long *p;
   if (len == 0 || len > SIZE_MAX / sizeof(long)) {
      /* Handle overflow */
   }
   p = (long *)malloc(len * sizeof(int));
   if (p == NULL) {
      /* Handle error */
   }
   /* ... */
   free(p);
}

...

To correct the noncompliant code example, sizeof(long) is used to size the memory allocation.

Code Block
bgColorccccff

void function(size_t len) {
   long *p;
   if (len == 0 || len > SIZE_MAX / sizeof(long)) {
      /* Handle overflow */
   }
   p = (long *)malloc(len * sizeof(long));
   if (p == NULL) {
      /* Handle error */
   }
   /* ... */
   free(p);
}

Alternatively, sizeof(*p) can be used to properly size the allocation.

Code Block
bgColorccccff

void function(size_t len) {
   long *p;
   if (len == 0 || len > SIZE_MAX / sizeof(*p)) {
      /* handle overflow */
   }
   p = (long *)malloc(len * sizeof(*p));
   if (p == NULL) {
      /*   handle error */
   }
   /* ... */
   free(p);
}

...

Code Block
if (a < SIZE_MAX / b && a > 0) ...

Related Vulnerabilities

Wiki Markup
[CVE-2009-0587|http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-0587] results from a violation of this rule. Before version 2.24.5, Evolution Data Server performed unchecked arithmetic operations on a {{size_t}} representing the length of an arbitrary input string and used the value to allocate space for a new buffer. Thus, an attacker could execute arbitrary code by inputting a long string, resulting in incorrect allocation and buffer overflow \[[xorl 2009|AA. C References#xorl 20090587]\].

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

...

Wiki Markup
\[[Coverity 07|AA. C References#Coverity 07]\]
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.3, "Memory Management Functions"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "XYB Buffer Overflow in Heap"
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 190|http://cwe.mitre.org/data/definitions/190.html], "Integer Overflow (Wrap or Wraparound)," and [CWE ID 131|http://cwe.mitre.org/data/definitions/131.html], "Incorrect Calculation of Buffer Size"
\[[Seacord 05|AA. C References#Seacord 05]\] Chapter 4, "Dynamic Memory Management," and Chapter 5, "Integer Security"
\[[xorl 2009|AA. C References#xorl 20090587]\] "CVE-2009-0587: Evolution Data Server Base64 Integer Overflows"

...

      08. Memory Management (MEM)      09. Input Output (FIO)