Upon return, functions should guarantee that any object returned by the function, or any modified value referenced by a pointer argument, is a valid object of function return type or argument type. Otherwise, type errors can occur in the program.
A good example is the null-terminated byte string type in C. If a string lacks the terminating null character, the program may be tricked into accessing storage after the string as legitimate data. A program may, as a result, process a string it should not process, which might be a security flaw in itself. It may also cause the program to abort, which might be a denial-of-service attack.
The emphasis of this recommendation is to avoid producing unterminated strings; it does not address processing of already existing unterminated strings. However, by preventing the creation of unterminated strings, the need to process them is greatly lessened.
Noncompliant Code Example
The standard strncpy()
function does not guarantee that the resulting string is null-terminated. If there is no null character in the first n
characters of the source
array, the result may not be null-terminated.
char *source; char a[NTBS_SIZE]; /* ... */ if (source) { char* b = strncpy(a, source, 5); // b == a } else { /* Handle null string condition */ }
Compliant Solution (strncpy_s()
, C11 Annex K)
The C11 Annex K strncpy_s()
function copies up to n
characters from the source array to a destination array. If no null character was copied from the source array, the n
th position in the destination array is set to a null character, guaranteeing that the resulting string is null-terminated.
char *source; char a[NTBS_SIZE]; /* ... */ if (source) { errno_t err = strncpy_s(a, sizeof(a), source, 5); if (err != 0) { /* Handle error */ } } else { /* Handle null string condition */ }
Risk Assessment
Failure to enforce type safety can result in type errors in the program.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
API07-C | Medium | Unlikely | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
CodeSonar | 8.1p0 | LANG.CAST.VALUE LANG.CAST.COERCE ALLOC.TM | Cast alters value |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
ISO/IEC TR 24772:2013 | String Termination [CJM] | Prior to 2018-01-12: CERT: Unspecified Relationship |
MITRE CWE | CWE-192 | Prior to 2018-01-12: |
MITRE CWE | CWE-227 | Prior to 2018-01-12: |
MITRE CWE | CWE-590 | Prior to 2018-01-12: |
MITRE CWE | CWE-686 | Prior to 2018-01-12: |
MITRE CWE | CWE-704 | Prior to 2018-01-12: |
MITRE CWE | CWE-761 | Prior to 2018-01-12: |
MITRE CWE | CWE-762 | Prior to 2018-01-12: |
MITRE CWE | CWE-843 | Prior to 2018-01-12: |
5 Comments
Robert Seacord
Add a second example that doesn't involve NTBS?
Martin Sebor
The concept of a NUL-terminated byte string is not represented by a type in C so the uses of
strncpy()
orstrncpy_s()
are unrelated to type safety. The noncompliant example on this page actually demonstrates a violation of STR32-C. Null-terminate byte strings as required. Unless there are examples of true type safety bugs that aren't already addressed by other existing rules (such as EXP39-C. Do not access a variable through a pointer of an incompatible type) I suggest this rule be removed.David Svoboda
Furthermore, it is not always feasible to validate that a string is null-termiated. What if a function returns a string it allocated on the heap, and expects the caller to free? The caller does not know the string length, and if the string is not null-terminated, the caller cannot verify this w/o overflowing the heap. The GNU getline() function is a good example of this.
Frank Martinez
Just for the record, strncpy() does not return "errno_t" but "char *".
David Svoboda
Fixed, thanks. (OTOH strncpy_s() does return errno_t)