Versions Compared

Key

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

...

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
#include <algorithm>

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

This hazard applies to any algorithm that takes a 'destination' iterator, expecting to fill it with values. Most of the STL algorithms expect the destination container to have sufficient space to hold the values provided.

Compliant Solution (Vector, resize())

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
#include <algorithm>

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

Compliant Solution (Vector, back_inserter())

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

#include <algorithm>

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

The front_insert_iterator works in a similar fashion to the back_insert_iterator, but it automatically pushes new elements to the front of the container, causing them to be listed in the container in reverse order. Since it uses the member push_front() method, it is not available for vectors.

Also note that using insert iterators is less efficient than using resize() becuase they expand the destination container one element at a time.

Risk Assessment

Copying data to a buffer that is too small to hold that data results in a buffer overflow. Attackers can exploit this condition to execute arbitrary code.

...

Wiki Markup
\[[ISO/IEC PDTR 24772|AA. C++ References#ISO/IEC PDTR 24772]\] "XYB Buffer Overflow in Heap," "XYW Buffer Overflow in Stack," and "XYZ Unchecked Array Indexing"
\[[Meyers 01|AA. C++ References#Meyers 01]\] Item 30: Make sure destination ranges are big enough
\[[MITRE 07|AA. C++ References#MITRE 07]\] [CWE ID 119|http://cwe.mitre.org/data/definitions/119.html], "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer"
\[[Seacord 05a|AA. C++ References#Seacord 05]\] Chapter 2, "Strings"
\[[VU#196240|AA. C++ References#VU196240]\]

...