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.

...

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

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 Modified Image Modified Image Modified