Versions Compared

Key

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

...

Code Block
bgColor#FFcccc
char *copy(size_t n, char const *str) {
  int i;
  char *p = (char *)malloc(n);
  if (p == NULL) {
    /* Handle malloc failure */
  }
  for ( i = 0; i < n; ++i ) {
    p[i] = *str++;
  }
  return p;
}

/* ... */

char str[] = "hi there";
char *p = copy(9sizeof(str), "hi there"str);

Signed integer overflow causes undefined behavior. The following are two possible conditions under which this code constitutes a serious vulnerability:

...

Code Block
bgColor#ccccff
char *copy(rsize_t n, char const *str) {
  rsize_t i;
  char *p;
  if (n > RSIZE_MAX) {
    /* Handle unreasonable object size error */
  }
  p = (char *)malloc(n);
  if (p == NULL) {
    /* Handle malloc failure */
  }
  for ( i = 0; i < n; ++i ) {
    p[i] = *str++;
  }
  return p;
}

/* ... */

char str[] = "hi there";
char *p = copy(sizeof(9str), "hi there"str);

Non-Compliant Code Example

In this non-compliant code example, an integer overflow is specifically looked for by checking whether length + 1 == 0 (that is, integer wrap around has occurred). If the test passes, a wrapper to malloc() is called to allocate the appropriate data block. When sizeof(int) == sizeof(long) UINT_MAX == ULONG_MAX, this code runs as expected, but if sizeof(long) > sizeof(int) ULONG_MAX > UINT_MAX, an integer overflow can occur when length is passed in to alloc() because the result is truncated down to an unsigned int.

Code Block
bgColor#FFcccc
void *alloc(unsigned int blocksize) {
  return malloc(blocksize);
}

int read_counted_string(int fd) {
  unsigned long length;
  unsigned char *data;

  if (read_integer_from_network(fd, &length) < 0) {
    return -1;
  }

  if (length + 1 == 0ULONG_MAX) {
    /* handle integer overflow */
  }

  data = (unsigned char*)alloc(length + 1);

  if (read_network_data(fd, data, length) < 0) {
    free(data);
    return -1;
  }
  data[length] = '\0';

  /* ... */
  free( data);
  return 0;
}

...

Code Block
bgColor#ccccff
void *alloc(rsize_t blocksize) {
  if (blocksize > RSIZE_MAX) {
    /* Handle error */
  }
  return malloc(blocksize);
}

int read_counted_string(int fd) {
  rsize_t length;
  unsigned char *data;

  if (read_integer_from_network(fd, &length) < 0) {
    return -1;
  }

  if (length + 1 == 0RSIZE_MAX) {
    /* handle integer overflow */
  }

  data = (unsigned char*)alloc(length + 1);

  if (read_network_data(fd, data, length) < 0) {
    free(data);
    return -1;
  }
  data[length] = '\0';

  /* ... */
  free( data);
  return 0;
}

...