Versions Compared

Key

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

...

Do not allow an expression of integral type to add to or subtract from a pointer or random access iterator when the resulting value would overflow the bounds of the container.

Noncompliant Code Example (std::vector)

In this noncompliant code example, a random access iterator from a std::vector is used in an additive expression, but the resulting value could be outside of the bounds of the container, and not a past-the-end value.

Code Block
bgColor#ffcccc
langcpp
#include <vector>
 
void f(const std::vector<int> &C) {
  for (auto I = C.begin(), E = I + 20; I != E; ++I) {
    std::cout << *I << std::endl;
  }
}

Compliant Solution (std::vector)

This compliant solution assumes that the programmer's intention was to process up to twenty items in the container. Instead of assuming all containers will have twenty or more elements, the size of the container is used to determine the upper bound on the addition.

...

This compliant solution also uses a named constant value in compliance with DCL06-CPP. Use meaningful symbolic constants to represent literal values in program logic.

Non-Compliant Code Example (Linear Address Space)

In this noncompliant code example, an attempt is made to determine if a pointer addition will cause a linear address space wraparound:

...

In GCC versions 4.2 and later, code that performs checks for wrapping that depend on undefined behavior (such as the code in this noncompliant code example) are optimized away; no object code to perform the check appears in the resulting executable program [VU#162289]. This is of special concern because it often results in the silent elimination of code that was inserted to provide a safety or security check. For GCC 4.2.4 and later, this optimization may be disabled for with the -fno-strict-overflow option.

Compliant Solution (Linear Address Space)

In this compliant solution, both references to buf are cast to std::uintptr_t. Because std::uinptr_t is an unsigned integral type of sufficient size to store a pointer value, C++ guarantees that it has modulo behavior.

...

This compliant solution works on architectures that provide a linear address space. Some word-oriented machines are likely to produce a word address with the high-order bits used as a byte selector, in which case this solution will fail. Consequently, this is not a portable solution.

Risk Assessment

If adding or subtracting an integer to a pointer results in a reference to an element outside the array or one past the last element of the array object, the behavior is undefined, but frequently leads to a buffer overflow or buffer underrun which can often be exploited to run arbitrary code. Iterators and STL containers exhibit the same behavior and caveats as pointers and arrays.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CTR38-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

Bibliography

[ISO/IEC 14882-2014]

5.7, "Additive Operators"
24.2.1, "In General"

[Banahan 03]5.3, "Pointers"
5.7, "Expressions involving pointers"

...