Copying data into an array 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 array container must be restricted based on the size of the destination arraycontainer, or, preferably, the destination array 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 often can also involve null-terminated character arrays (NTCA)strings. Consult VOID STR31STR35-CPP. Guarantee that storage for character arrays strings has sufficient space for character data and the null terminator for for specific examples of this rule that involve NTCAstrings.
Most such copies are Copies can be made with the std::memcpy()
function function. However, the std::memmove()
function and the std::memset()
function functions can also have the same vulnerabilities because they overwrite a block of memory without checking that the block is valid.
Noncompliant Code Example (Array)
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 | ||||
---|---|---|---|---|
| ||||
enum { WORKSPACE_SIZE = 256 };
void func(const int src[], size_t len) {
int dest[WORKSPACE_SIZE];
memcpy(dest, src, len * sizeof(int));
/* ... */
}
|
Compliant Solution (Array)
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 | ||||
---|---|---|---|---|
| ||||
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);
/* ... */
}
|
Noncompliant Code Example (Vector)
Such issues are not limited to C standard library functions; STL generic algorithms like 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 Vectors can be subject to the same vulnerabilities as array datatypes. The std::copy
function 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 std::copy()
does nothing to expand the dest
vector, thus the program will overflow the buffer on copying the first element.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <algorithm> #include <vector> void funcf(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 code example compliant solution enlarges the capacity of the vector before starting the copyo.prior to the copy operation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <algorithm> #include <vector> void funcf(const std::vector<int> &src) { // vector<int>Initialize dest; with src.size() default-inserted elements. std::vector<int> dest.resize( src.size()); std::copy( src.begin(), src.end(), dest.begin()); //* ... */ } |
Compliant Solution (
...
std::
back_inserter()
)
An alternative safe 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 guarantees the destination container will become sufficiently large enough to hold the elements provided.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <algorithm> #include <iterator> #include <vector> void funcf(const std::vector<int> &src) { std::vector<int> dest; std::copy( src.begin(), src.end(), std::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.
...
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 |
---|---|---|---|---|---|
ARR33CTR33-CPP | highHigh | likelyLikely | mediumMedium | P18 | L1 |
Automated Detection
Coverity Code Advisor version 7.5 can detect violations of this rule.
Fortify SCA Version 5.0 can detect violations of this rule.
Splint Version 3.1.1 can detect violations of this rule.
Compass/ROSE can detect some violations of this rule.
...
Tool | Version | Checker | Description |
---|---|---|---|
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the the CERT website.
Other Languages
...
Related Guidelines
...
...
...
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 |
[MITRE] CWE ID 119, "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer"
[MITRE] CWE ID 805, "Buffer Access with Incorrect Length Value"
[Seacord 05a] Chapter 2, "Strings"
[VU#196240]
CTR32-CPP. Use valid references, pointers, and iterators to reference elements of a container 06. Containers (CTR) CTR34-CPP. Use Valid Iterator Ranges