...
Vulnerabilities that result from copying data to an undersized buffer often involve null-terminated byte strings character arrays (NTBSNTCA). Consult STR31-CPP. Guarantee that storage for character arrays has sufficient space for character data and the null terminator for specific examples of this rule that involve NTBSNTCA.
Noncompliant Code Example
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]; if (len > WORKSPACE_SIZE) { /* Handle Error */ } memcpy(dest, src, sizeof(int)*len); /* ... */ } |
Compliant Solution (Dynamic Allocation)
Noncompliant Code Example (Vector)
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 elementAlternatively, memory for the destination buffer (dest
) can be dynamically allocated to ensure it is large enough to hold the data in the source buffer (src
). Note that this solution checks for numeric overflow (see INT32-CPP. Ensure that operations on signed integers do not result in overflow).
Code Block | ||
---|---|---|
| ||
void func(const intvector<int> src[], size_t len) { intvector<int> *dest; ifcopy( src.begin(len > SIZE_MAX/sizeof(int)) { ), src.end(), dest.begin()); /* handle integer overflow ... */ } dest = (int *)malloc(sizeof(int) * len |
Compliant Solution (Vector)
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 | ||
---|---|---|
| ||
void func(const vector<int> src); if (dest == NULL) { vector<int> dest; /* Couldn't get the memory - recover */ } memcpy(dest, src, sizeof(int) * len); dest.resize( src.size()); copy( src.begin(), src.end(), dest.begin()); /* ... */ free(dest); } |
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.
...
This rule appears in the C Secure Coding Standard as ARR33-C. Guarantee that copies are made into storage of sufficient size.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C++ References#ISO/IEC 9899-1999]\] Section 7.21.2, "Copying functions," Section 7.21.2.1, "The memcpy function," and Section 5.1.2.2.1, "Program Startup"
\[[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"
\[[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]\] |
...