Versions Compared

Key

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

...

Improper use of functions that limit copies with a size specifier, such as memcpy(), may result in a buffer overflow. In this noncompliant code example, an array of integers is copied from src to dest using memcpy(). However, the programmer mistakenly specified the amount to copy based on the size of src, which is stored in len, rather than the space available in dest. If len is greater than 256, then a buffer overflow will occur.

Code Block
bgColor#FFCCCC
langcpp
enum { WORKSPACE_SIZE = 256 };

void func(const int src[], size_t len) {
  int dest[WORKSPACE_SIZE];
  memcpy(dest, src, len * sizeof(int));
  /* ... */
}

...

The amount of data copied should be limited based on the available space in the destination buffer. This can be accomplished by adding a check to ensure the amount of data to be copied from src can fit in dest.

Code Block
bgColor#ccccff
langcpp
enum { WORKSPACE_SIZE = 256 };

void func(const int src[], size_t len) {
  int dest[WORKSPACE_SIZE];
  if (len > WORKSPACE_SIZE) {
      /* Handle Error */
  }
  memcpy(dest, src, sizeof(int)*len);
  /* ... */
}

...

Vectors can be subject to the same vulnerabilities. The copy function provides no inherent bounds checking, and can lead to a buffer overflow. In this noncompliant code example, a vector of integers is copied from src to dest using copy(). Since copy() does nothing to expand the dest vector, thus the program will overflow the buffer on copying the first element.

Code Block
bgColor#FFCCCC
langcpp
#include <algorithm>

void func(const vector<int> src) {
  vector<int> dest;
  copy( src.begin(), src.end(), dest.begin());
  /* ... */
}

...

The proper way to use copy() is to ensure the destination container can hold all the elements being copied to it. This code example enlarges the capacity of the vector before starting the copyo.

Code Block
bgColor#ccccff
langcpp
#include <algorithm>

void func(const vector<int> src) {
  vector<int> dest;
  dest.resize( src.size());
  copy( src.begin(), src.end(), dest.begin());
  /* ... */
}

...

An alternative safe approach is to supply a back_insert_iterator as the destination argument. This iterator expands the destination container by one element for each element supplied by the algorithm. This guarantees the destination container will become sufficiently large enough to hold the elements provided.

Code Block
bgColor#ccccff
langcpp
#include <algorithm>

void func(const vector<int> src) {
  vector<int> dest;
  copy( src.begin(), src.end(), back_inserter( dest));
  /* ... */
}

...