...
In this compliant solution, the parameter pos
is declared as size_t
, which prevents passing the passing of negative arguments.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstddef> void insert_in_table(int *table, std::size_t tableSize, std::size_t pos, int value) { if (pos >= tableSize) { // Handle error return; } table[pos] = value; } |
...
In this noncompliant code example, a std::vector
is used in place of a pointer and size pair. The function performs a range check to ensure that pos
does not exceed the upper bound of the container. Because pos
is declared as a (signed) long long
, this parameter can assume a negative value. On systems where std::vector::size_type
is ultimately implemented as an unsigned int
(such as with Microsoft Visual Studio 2013), the usual arithmetic conversions applied for the comparison expression will convert the unsigned value to a signed value. If pos
has a negative value, this comparison will not fail, resulting in a write outside the bounds of the std::vector
object when the negative value is interpreted as a large unsigned value in the indexing operator.
...
In this compliant solution, the parameter pos
is declared as size_t
, which ensures that the comparison expression will fail when a large, positive value (converted from a negative argument) is given:.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <vector> void insert_in_table(std::vector<int> &table, std::size_t pos, int value) { if (pos >= table.size()) { // Handle error return; } table[pos] = value; } |
...
This compliant solution tests for iterator validity before attempting to dereference b
:.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <iterator> template <typename ForwardIterator> void f_imp(ForwardIterator b, ForwardIterator e, int val, std::forward_iterator_tag) { while (b != e) { *b++ = val; } } template <typename ForwardIterator> void f(ForwardIterator b, ForwardIterator e, int val) { typename std::iterator_traits<ForwardIterator>::iterator_category cat; f_imp(b, e, val, cat); } |
...
Using an invalid array or container index can result in an arbitrary memory overwrite or abnormal program termination.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CTR50-CPP | High | Likely | High | P9 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| overflow_upon_dereference | |||||||
CodeSonar |
| LANG.MEM.BO | Buffer overrun | ||||||
Helix QAC |
| C++3139, C++3140 DF2891 | |||||||
Klocwork |
| ABV.ANY_SIZE_ARRAY ABV.GENERAL ABV.GENERAL.MULTIDIMENSION ABV.STACK ABV.TAINTED SV.TAINTED.ALLOC_SIZE SV.TAINTED.CALL.INDEX_ACCESS SV.TAINTED.CALL.LOOP_BOUND SV.TAINTED.INDEX_ACCESS | |||||||
LDRA tool suite |
| 45 D, 47 S, 476 S, 489 S, 64 X, 66 X, 68 X, 69 X, 70 X, 71 X, 79 X | Partially implemented | ||||||
Parasoft C/C++test |
| CERT_CPP-CTR50-a | Guarantee that container indices are within the valid range | |||||||
Polyspace Bug Finder |
| CERT C++: CTR50-CPP | Checks for:
Rule partially covered. | ||||||
PVS-Studio |
| V781 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C Coding Standard | ARR30-C. Do not form or use out-of-bounds pointers or array subscripts |
MITRE CWE | CWE 119, Failure to Constrain Operations within the Bounds of a Memory Buffer CWE 129, Improper Validation of Array Index |
Bibliography
[ISO/IEC 14882-2014] | Clause 23, "Containers Library" |
[ISO/IEC TR 24772-2013] | Boundary Beginning Violation [XYX] Wrap- |
Around Error [XYY] Unchecked Array Indexing [XYZ] |
[Viega |
2005] | Section 5.2.13, "Unchecked Array Indexing" |
...
...