Versions Compared

Key

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

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.

Vulnerabilities that result from copying data to an undersized buffer can also involve null-terminated strings. Consult STR35 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 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
bgColor#ccccff
langcpp
#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
bgColor#ccccff
langcpp
#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
bgColor#ccccff
langcpp
#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
bgColor#FFCCCC
langcpp
#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
bgColor#ccccff
langcpp
#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
bgColor#ccccff
langcpp
#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

Remediation Cost

Priority

Level

CTR33

CTR52-CPP

High

Likely

Medium

P18

L1

Automated Detection

Tool

Version

Checker

Description

   

Astrée

Include Page
Astrée_V
Astrée_V

invalid_pointer_dereference

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

BADFUNC.BO.*
LANG.MEM.BO
LANG.MEM.TBA

A collection of warning classes that report uses of library functions prone to internal buffer overflows.
Buffer Overrun
Tainted Buffer Access

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF3526, DF3527, DF3528, DF3529, DF3530, DF3531, DF3532, DF3533, DF3534


Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V
CERT_CPP-CTR52-a
Do not pass empty container iterators to std algorithms as destinations
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: CTR52-CPPChecks for library functions overflowing sequence container (rule partially covered).
 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

Subclause 25.3, "Mutating Sequence Operations"

[ISO/IEC
PDTR
TR 24772-2013]
"XYB
Buffer Overflow in Heap
," "XYW
[XYB]
Buffer Overflow in Stack
," and "XYZ
[XYW]
Unchecked Array Indexing
"
[XYZ]
[Meyers
01
2001]Item 30
: Make sure destination ranges are big enough

 

, "Make Sure Destination Ranges Are Big Enough"


...

Image Added Image Added Image AddedCTR32-CPP. Use valid references, pointers, and iterators to reference elements of a container      006. Containers (CTR)      CTR34-CPP. Use valid iterator ranges