Versions Compared

Key

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

Functions that have an array as a parameter should also have an additional parameter that indicates the maximum number of elements that can be stored in the array.   This additional That parameter is required to ensure that the function does not access memory outside the bounds of the array and adversely influence program execution.  This additional parameter  It should be present for each array parameter (in other words, the existence of each array parameter implies the existence of a complementary parameters representing parameter that represents 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 contiguous block of memory in which one or more elements of a particular type are (potentially) stored.   These terms are all effectively synonymous and represent the same potential for error.

Also note that this recommendation suggests that the parameter accompanying array parameters indicate indicates the maximum number of elements that can be stored in the array and , not the maximum size, in bytes, of the array.  This is , because,

  1. It does not make sense to think of array sizes in bytes in all cases.  For cases—for example, it makes little sense to think in the case of an array of integers in its size in bytes.
  2. If the size in bytes of the array is required, it can be derived from the number of elements in the array.
  3. It is better not to add to the cognitive load of the function user of the function and it is probably easier for the user to think of the size by requiring the user to calculate the size in bytes of the array in terms of its elements.

In most cases, the distinction between the number of elements and number of bytes is moot because : there is a clear mapping between the two, and it is easier to think in terms of number of elements anyway.   Unfortunately, this issue can become muddled when working with multibyte strings as because the logical entity being manipulated differs from that of the type being used to implement it.   Here, it is important to remind oneself remember that the type of the array is a character and , not a multibyte character.   Accordingly, the number of elements in the array is represented as a number of characters.

...

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.Standard, subclause 7.24 [ISO/IEC 9899:2011]:

Code Block
bgColor#FFcccc
langc

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 problem with these functions is twofold.  These functions have two problems. First, there is no indication of the size of the first array, s1.   ThusAs a result, it is not possible to discern within the function how large s1 is and how many elements may be written into it.   Second, while it  it appears that a size is supplied for s2 is supplied this is, in fact, a , but the size_t parameter n actually gives the number of elements to copy.   ThusConsequently, there is no guarantee that the elements being copied are members of way for either function to determine the size of the array s2.

Compliant Solution

The above C strncpy() and strncat() functions could be improved by adding element count parameters as follows:

Code Block
bgColor#ccccff
langc

char *improved_strncpy(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count, size_t n);
char *improved_strncat(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count, size_t n);

Note that for strncpy() it makes sense to maintain the n parameter as the caller may only wish to copy a subset of The n parameter is used to specify a number of elements to copy that is less than the total number of elements .  For strncat() the n parameter is no longer required. in the source string.

Compliant Solution (

...

C11 Annex K)

The C Standard, Annex K (normative) Bounds-checking interfaces, defines bounds-checking versions of standard C library string-handling functions:TR24731-1, which will be an appendix in C1x, prescribes the addition of "secure" versions of the noncompliant examples provided above.

Code Block
bgColor#ccccff
langc

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 above and the secure versions from TR24731-1Annex K.   First, the TR24731-1 versions the Annex K versions use rsize_t instead of size_t.  This allows , which allows the size to be compared against the reasonable limit for a single object, RSIZE_MAX.   Second, the TR24731-1 versions the Annex K 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.

Exceptions

API02-C-EX1: Functions that can guarantee via their runtime-constraint handlers that no out-of-bounds read or write occurs may omit the maximum-elements argument. For instance, the s2 parameter to strcat_s() needs no max parameter.

Code Block
bgColor#ccccff
langc
errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2);

As another example, consider strcpy_s():

Code Block
bgColor#ccccff
langc
errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);

This function provides no explicit maximum argument to s2. However, it requires that s1max be larger than s2, thereby preventing an out-of-bounds read.

Risk Assessment

Failure to do so follow this recommendation can result in improper memory accesses and buffer overflows in that are detrimental to the correct and continued execution of the program.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

API02-C

high

likely

high

P27

L1

High

Likely

High

P9

L2

Automated Detection

Tool

Version

Checker

Description

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
BADFUNC.BO.*

A collection of checks that report uses of library functions prone to internal buffer overflows.

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-API02-a
CERT_C-API02-b

Avoid using unsafe string functions which may cause buffer overflows
Don't use unsafe C functions that do write to range-unchecked buffers

Related Vulnerabilities

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

Other Languages

References

...

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

Bibliography

[ISO/IEC 9899:2011]Annex K (normative) Bounds-checking Interfaces


...

Image Added Image Added Image Added