API02-C. Functions that read or write to or from an array should take an argument to specify the source or target sizeFunctions that take an array have an array as a parameter should also take have an additional parameter that indicates the maximum number of elements that can be stored in the array. This additional parameter is required to ensure that the function does not read or write access memory outside the bounds of the array and adversely influence program execution. This additional parameter should be present for each array parameter (in other words, the existence of each array parameter implies the existence of a complementary parameters representing the maximum number of elements in the array).
Note that the word array is used in this recommendation to mean array, string, or any other pointer to a continguous contiguous block of memory in which one or more than one element elements of a type is are (potentially) stored. These terms are all effectively synonomous synonymous and represent the same potential for error.
...
It is not necessary to go beyond the standard C library to find examples that violate this recommendation. This is because the C language often prioritizes performance at the expense of robustness. The following are two examples from §7.21 of the C standard.
Code Block | ||
---|---|---|
| ||
char *strncpy(char * restrict s1, const char * restrict s2, size_t n); char *strncat(char * restrict s1, const char * restrict s2, size_t n); |
...
The above functions could be remedied improved by adding element count parameters as follows:
Code Block | ||
---|---|---|
| ||
char *strncpy(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count, size_t n); char *strncat(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count); |
Note that for strncpy() it makes sense to maintain the n parameter as the caller may only wish to copy a subset of the total number of elements. For strncat() the n parameter is no longer required. TR24731-1, which will be an appendix in C1x, prescribes the addition of "secure" versions of the noncompliant examples provided above.
Code Block | ||
---|---|---|
| ||
errno_t strncpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n);
errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2);
|
There are two notable differences between the compliant solution and the secure versions from TR24731-1. First, the TR24731-1 versions use rsize_t instead of size_t. This allows the size to compared against the reasonable limit for a single object, RSIZE_MAX. Second, the TR24731-1 versions do not require an element count for the second array. Consequently, these functions have limited ability to validate the input for s2. However, a size value for s1 is required so memory outside of the range for s1 should not be overwritten.
Risk Assessment
Failure to do so can result in type errors buffer overflows in the program.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
API02-C | low high | probable likely | high | P6 P27 | L2 L1 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
References
Wiki Markup |
---|
\[[ISO/IEC TR 24731-1:2007|AA. C References#ISO/IEC TR 24731-1-2007]\] |