You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Copying data into an array that is not large enough to hold that data results in a buffer overflow. To prevent such errors, data copied to the destination array must be restricted based on the size of the destination array, or, preferably, the destination array must be guaranteed to be large enough to hold the data to be copied.

Vulnerabilities that result from copying data to an undersized buffer often involve null-terminated byte strings (NTBS). Consult STR31-CPP. Guarantee that storage for strings has sufficient space for character data and the NULL terminator for specific examples of this rule that involve NTBS.

Noncompliant Code Example

Improper use of functions that limit copies with a size specifier, such as memcpy(), may result in a buffer overflow. In this noncompliant code example, an array of integers is copied from src to dest using memcpy(). However, the programmer mistakenly specified the amount to copy based on the size of src, which is stored in len, rather than the space available in dest. If len is greater than 256, then a buffer overflow will occur.

enum { WORKSPACE_SIZE = 256 };

void func(const int src[], size_t len) {
  int dest[WORKSPACE_SIZE];
  memcpy(dest, src, len * sizeof(int));
  /* ... */
}

Compliant Solution (Bounds Checking)

The amount of data copied should be limited based on the available space in the destination buffer. This can be accomplished by adding a check to ensure the amount of data to be copied from src can fit in dest.

enum { WORKSPACE_SIZE = 256 };

void func(const int src[], size_t len) {
  int dest[WORKSPACE_SIZE];
  if (len > WORKSPACE_SIZE) {
      /* Handle Error */
  }
  memcpy(dest, src, sizeof(int)*len);
  /* ... */
}

Compliant Solution (Dynamic Allocation)

Alternatively, memory for the destination buffer (dest) can be dynamically allocated to ensure it is large enough to hold the data in the source buffer (src). Note that this solution checks for numeric overflow (see INT32-CPP. Ensure that operations on signed integers do not result in overflow).

void func(const int src[], size_t len) {
  int *dest;
  if (len > SIZE_MAX/sizeof(int)) {
   /* handle integer overflow */
  }
  dest = (int *)malloc(sizeof(int) * len);
  if (dest == NULL) {
     /* Couldn't get the memory - recover */
  }
  memcpy(dest, src, sizeof(int) * len);

  /* ... */

  free(dest);
}

Risk Assessment

Copying data to a buffer that is too small to hold that data results in a buffer overflow. Attackers can exploit this condition to execute arbitrary code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ARR33-CPP

high

likely

medium

P18

L1

Automated Detection

Fortify SCA Version 5.0 can detect violations of this rule.

Splint Version 3.1.1 can detect violations of this rule.

Compass/ROSE can detect some violations of this rule.

Klocwork Version 8.0.4.16 can detect violations of this rule with the ABR checker.

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 ARR33-C. Guarantee that copies are made into storage of sufficient size.

References

[[ISO/IEC 9899:1999]] Section 7.21.2, "Copying functions," Section 7.21.2.1, "The memcpy function," and Section 5.1.2.2.1, "Program Startup"
[[ISO/IEC PDTR 24772]] "XYB Buffer Overflow in Heap," "XYW Buffer Overflow in Stack," and "XYZ Unchecked Array Indexing"
[[MITRE 07]] CWE ID 119, "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer"
[[Seacord 05a]] Chapter 2, "Strings"
[[VU#196240]]


ARR32-CPP. Ensure size arguments for variable length arrays are in a valid range      06. Arrays (ARR)       ARR34-CPP. Ensure that array types in expressions are compatible

  • No labels