Copying data into a container that is not large enough to hold that data results in a buffer overflow. To prevent such errors, data copied to the destination container must be restricted based on the size basis of the destination container's size, or , preferably, the destination container must be guaranteed to be large enough to hold the data to be copied.
...
Copies can be made with the std::memcpy() function. However, the std::memmove() and std::memset() functions can also have the same vulnerabilities because they overwrite a block of memory without checking that the block is valid. Such issues are not limited to C standard library functions; standard template library (STL) generic algorithms like , such as std::copy(), std::fill(), and std::transform(), also assume valid output buffer sizes .Note that since iterators are a generalization of pointers, this rule applies to iterators and pointers equally [ISO/IEC 14882-2014].
Noncompliant Code Example
STL containers can be subject to the same vulnerabilities as array datatypesdata types. The std::copy algorithm () algorithm 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 std::copy(). Since Because std::copy() does nothing to expand the dest vector, the program will overflow the buffer on copying the first element.
...
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 (
...
Sufficient Initial Capacity)
The proper way to use std::copy() is to ensure the destination container can hold all the elements being copied to it. This compliant solution enlarges the capacity of the vector prior to the copy operation:.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <algorithm>
#include <vector>
void f(const std::vector<int> &src) {
// Initialize dest with src.size() default-inserted elements.
std::vector<int> dest(src.size());
std::copy(src.begin(), src.end(), dest.begin());
// ...
}
|
Compliant Solution (
...
Per-Element Growth)
An alternative approach is to supply a std::back_insert_iterator as the destination argument. This iterator expands the destination container by one element for each element supplied by the algorithm. This , which guarantees the destination container will become sufficiently large enough to hold the elements provided.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <algorithm>
#include <iterator>
#include <vector>
void f(const std::vector<int> &src) {
std::vector<int> dest;
std::copy(src.begin(), src.end(), std::back_inserter(dest));
// ...
} |
Compliant Solution (Assignment)
The simplest solution is to construct dest from src directly, as in this compliant solution:.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <vector>
void f(const std::vector<int> &src) {
std::vector<int> dest(src);
// ...
} |
Noncompliant Code Example
In this noncompliant code example, std::fill_n() is used to fill a buffer with 10 instances of the value 0x42. However, the buffer has not allocated any space for the elements, so this operation results in a buffer overflow.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <algorithm>
#include <vector>
void f() {
std::vector<int> v;
std::fill_n(v.begin(), 10, 0x42);
} |
Compliant Solution (Sufficient Initial Capacity)
This compliant solution ensures the capacity of the vector is sufficient before attempting to fill the container.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <algorithm> #include <vector> void f() { std::vector<int> v(10); std::fill_n(v.begin(), 10, 0x42); } |
However, this compliant solution is inefficient. The constructor will default-construct 10 elements of type int, which are subsequently replaced by the call to std::fill_n(), meaning that each element in the container is initialized twice.
Compliant Solution (Fill Initialization)
This compliant solution initializes v to 10 elements whose values are all 0x42.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <algorithm>
#include <vector>
void f() {
std::vector<int> v(10, 0x42);
} |
Risk Assessment
Copying data to a buffer that is too small to hold that the data results in a buffer overflow. Attackers can exploit this condition to execute arbitrary code.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|
CTR52-CPP | High | Likely | No |
No |
P9 |
L2 |
Automated Detection
Tool | Version | Checker | Description |
|---|
| Astrée |
| invalid_pointer_dereference | |||||||
| CodeSonar |
| BADFUNC.BO.* | A collection of warning classes that report uses of library functions prone to internal buffer overflows. | ||||||
| Helix QAC |
| DF3526, DF3527, DF3528, DF3529, DF3530, DF3531, DF3532, DF3533, DF3534 | |||||||
| Klocwork |
| ITER.END.OUTPARAM.MIGHT ITER.END.OUTPARAM.MUST | |||||||
| Parasoft C/C++test |
| CERT_CPP-CTR52-a | Do not pass empty container iterators to std algorithms as destinations | ||||||
| Polyspace Bug Finder |
| CERT C++: CTR52-CPP | Checks for library functions overflowing sequence container (rule partially covered). | ||||||
| Security Reviewer - Static Reviewer | 6.02 | C01 C04 | Fully implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| SEI CERT C++ Coding Standard | STR50-CPP. Guarantee that storage for strings has sufficient space for character data and the null terminator |
| SEI CERT C Coding Standard | ARR38-C. Guarantee that library functions do not form invalid pointers |
| MITRE CWE | CWE 119, Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer CWE 805, Buffer Access with Incorrect Length Value |
Bibliography
| [ISO/IEC 14882-2014] | Subclause 25.3, "Mutating Sequence Operations" |
| [ISO/IEC |
| TR 24772-2013] |
| Buffer Overflow in Heap |
| [XYB] Buffer Overflow in Stack |
| [XYW] Unchecked Array Indexing |
| [XYZ] |
| [Meyers |
| 2001] | Item 30 |
...
| , "Make Sure Destination Ranges Are Big Enough" |
...