Versions Compared

Key

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

Ensuring that array references are within the bounds of the array is almost entirely the responsibility of the programmer.

Noncompliant Code Example

This noncompliant code example shows a function insert_in_table() that has two int paramters, pos and value, both of which can be influenced by data originating from untrusted sources. The function uses a global variable table to determine if storage has been allocated for an array of 100 integer elements and allocates the memory if it has not already been allocated.

Code Block
bgColor#ffcccc
enum { TABLESIZE = 100 };

int *table = NULL;

int insert_in_table(int pos, int value){
  if (!table) {
    table = (int *)malloc(sizeof(int) * TABLESIZE);
  }
  if (pos >= TABLESIZE) {
    return -1;
  }
  table[pos] = value;
  return 0;
}

The function performs a range check to ensure that pos does not exceed the upper bound of the array but fails to check the lower bound for table. Because pos has been declared as a (signed) int, this parameter can easily assume a negative value, resulting in a write outside the bounds of the memory referenced by table.

Compliant Solution

In this compliant solution, the parameter pos is declared as size_t, which prevents 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
bgColor#ccccff
enum { TABLESIZE = 100 };

int *table = NULL;

int insert_in_table(size_t pos, int value){
  if (!table) {
    table = (int *)malloc(sizeof(int) * TABLESIZE);
  }
  if (pos >= TABLESIZE) {
    return -1;
  }
  table[pos] = value;
  return 0;
}

Risk Assessment

Using an invalid array index can result in an arbitrary memory overwrite or abnormal program termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ARR30-CPP

high

likely

high

P9

L2

Automated Detection

The LDRA tool suite Version 7.6.0 can detect violations of this rule.

Klocwork Version 8.0.4.16 can detect violations of this rule with the ABR, ABV.TAINTED, and SV.TAINTED.INDEX_ACCESS checkers.

Compass/ROSE can detect some violations of this rule. In particular, if a signed index to an array is being verified, it ensures that the value is also compared against 0.

Related Vulnerabilities

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

Other Languages

This rule appears in the C Secure Coding Standard as ARR30-C. Guarantee that array indices are within the valid range.

References

Wiki Markup
\[[ISO/IEC 9899:1999|AA. C++ References#ISO/IEC 9899-1999]\] Section 6.7.5.2, "Array declarators"
\[[ISO/IEC PDTR 24772|AA. C++ References#ISO/IEC PDTR 24772]\] "XYX Boundary Beginning Violation," "XYY Wrap-around Error," and "XYZ Unchecked Array Indexing"
\[[MITRE 07|AA. C++ References#MITRE 07]\] [CWE ID 129|http://cwe.mitre.org/data/definitions/129.html], "Unchecked Array Indexing"
\[[Viega 05|AA. C++ References#Viega 05]\] Section 5.2.13, "Unchecked array indexing"


ARR02-CPP. Explicitly specify array bounds, even if implicitly defined by an initializer      06. Arrays (ARR)       ARR31-CPP. Use consistent array notation across all source files