...
In this compliant solution, the parameter pos is declared as size_t, which prevents passing the passing of negative arguments (see INT01-CPP. Use rsize_t or size_t for all integer values representing the size of an object).
| 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;
}
|
...
In this noncompliant code example, it is possible that the the f_imp() function is given a valid iterator but that the iterator is not within a valid range. For instance, if f() were called with iterators obtained from an empty container, the end() iterator could be the (correct) ending iterator e for a container, and b is an iterator from the same container. However, it is possible that b is not within the valid range of its container. For instance, if the container were empty, b would equal e and be improperly dereferenced.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iterator>
template <typename ForwardIterator>
void f_imp(ForwardIterator b, ForwardIterator e, int val, std::forward_iterator_tag) {
do {
*b++ = val;
} while (b != e);
}
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);
} |
...
This compliant solution tests for iterator validity before attempting to dereference the forward iterator: 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 |
|---|
Detectable | Repairable | Priority | Level |
|---|---|---|---|
CTR50-CPP | High | Likely | No |
No | 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 | |||||||
| 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" |
...
...