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 on the 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.
Vulnerabilities that result from copying data to an undersized buffer can also involve null-terminated strings. Consult STR50-CPP. Guarantee that storage for strings has sufficient space for character data and the null terminator for specific examples of this rule that involve strings.
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 such as std::copy()
, std::fill()
, and std::transform()
also assume valid output buffer sizes.
Note that because 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 data types. The std::copy
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()
. Because std::copy()
does nothing to expand the dest
vector, the program will overflow the buffer on copying the first element.
#include <algorithm> #include <vector> void f(const std::vector<int> &src) { std::vector<int> dest; std::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 (std::vector::resize()
)
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:
#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 (std::
back_inserter()
)
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, which guarantees the destination container will become sufficiently large to hold the elements provided.
#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:
#include <vector> void f(const std::vector<int> &src) { std::vector<int> dest(src); // ... }
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.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CTR52-CPP | High | Likely | Medium | P18 | L1 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
CERT C++ Coding Standard | STR50-CPP. Guarantee that storage for strings has sufficient space for character data and the null terminator |
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] | 25.3, "Mutating Sequence Operations" |
[ISO/IEC PDTR 24772] | "XYB Buffer Overflow in Heap," "XYW Buffer Overflow in Stack," and "XYZ Unchecked Array Indexing" |
[Meyers 01] | Item 30: Make sure destination ranges are big enough |