Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: swapped NCCEs

...

STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator is a specific instance of this rule.

Noncompliant Code Example (Pointer)

In this noncompliant code example, inadequate space is allocated for a struct tm object because the size of the pointer is being used to determine the size of the pointed-to object:

Code Block
bgColor#FFcccc
langc
#include <stdlib.h>
#include <time.h>
 
struct tm *make_tm(int year, int mon, int day, int hour,
                   int min, int sec) {
  struct tm *tmb;
  tmb = (struct tm *)malloc(sizeof(tmb));
  if (tmb == NULL) {
    return NULL;
  }
  *tmb = (struct tm) {
    .tm_sec = sec, .tm_min = min, .tm_hour = hour,
    .tm_mday = day, .tm_mon = mon, .tm_year = year
  };
  return tmb;
}

Compliant Solution (Pointer)

 In this compliant solution, the correct amount of memory is allocated for the struct tm object. When allocating  space for a single object, passing the (dereferenced) pointer type to the sizeof operator is a simple way to allocate sufficient memory. Because the sizeof operator does not evaluate its operand, dereferencing an uninitialized or null pointer in this context is well-defined behavior.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <time.h>
 
struct tm *make_tm(int year, int mon, int day, int hour,
                   int min, int sec) {
  struct tm *tmb;
  tmb = (struct tm *)malloc(sizeof(*tmb));
  if (tmb == NULL) {
    return NULL;
  }
  *tmb = (struct tm) {
    .tm_sec = sec, .tm_min = min, .tm_hour = hour,
    .tm_mday = day, .tm_mon = mon, .tm_year = year
  };
  return tmb;
}

Noncompliant Code Example (Integer)

In this noncompliant code example, an array of of long is  is allocated and assigned to to p. The code attempts to check for unsigned integer overflow in compliance with INT30-C. Ensure that unsigned integer operations do not wrap and  and also ensures that len is not equal to zero. (See MEM04-C. Beware of zero-length allocations.) However, because because sizeof(int) is  is used to compute the size, and not not sizeof(long), an  an insufficient amount of memory can be allocated on allocated on implementations where where sizeof(long) is  is larger than than sizeof(int) . Consequently, despite the overflow check, the multiplication in the malloc() call  call still violates INT30-C.

Code Block
bgColor#FFcccc
langc
#include <stdint.h>
#include <stdlib.h>
 
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);
}

Compliant Solution (Integer)

This compliant solution uses sizeof(long) to correctly size the memory allocation:

Code Block
bgColor#ccccff
langc
#include <stdint.h>
#include <stdlib.h>

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);
}

Compliant Solution (Integer)

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

Code Block
bgColor#ccccff
langc
#include <stdint.h>
#include <stdlib.h>
 
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);
}

Noncompliant Code Example (Pointer)

In this noncompliant code example, inadequate space is allocated for a struct tm object because the size of the pointer is being used to determine the size of the pointed-to object:

Code Block
bgColor#FFcccc
langc
#include <stdlib.h>
#include <time.h>
 
struct tm *make_tm(int year, int mon, int day, int hour,
                   int min, int sec) {
  struct tm *tmb;
  tmb = (struct tm *)malloc(sizeof(tmb));
  if (tmb == NULL) {
    return NULL;
  }
  *tmb = (struct tm) {
    .tm_sec = sec, .tm_min = min, .tm_hour = hour,
    .tm_mday = day, .tm_mon = mon, .tm_year = year
  };
  return tmb;
}

Compliant Solution (Pointer)

 In this compliant solution, the correct amount of memory is allocated for the struct tm object. When allocating  space for a single object, passing the (dereferenced) pointer type to the sizeof operator is a simple way to allocate sufficient memory. Because the sizeof operator does not evaluate its operand, dereferencing an uninitialized or null pointer in this context is well-defined behavior.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <time.h>
 
struct tm *make_tm(int year, int mon, int day, int hour,
                   int min, int sec) {
  struct tm *tmb;
  tmb = (struct tm *)malloc(sizeof(*tmb));
  if (tmb == NULL) {
    return NULL;
  }
  *tmb = (struct tm) {
    .tm_sec = sec, .tm_min = min, .tm_hour = hour,
    .tm_mday = day, .tm_mon = mon, .tm_year = year
  };
  return tmb;
}

Risk Assessment

Providing invalid size arguments to memory allocation functions can lead to buffer overflows and the execution of arbitrary code with the permissions of the vulnerable process.

...