Strings must contain a null-termination character at or before the address of the last element of the array before they can be safely passed as arguments to standard string-handling functions, such as {{ Wiki Markup strcpy()
}} or {{strlen()
}}. This is because these functions, as well as other string-handling functions defined by C99 \ [[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\], depend on the existence of a null-termination character to determine the length of a string. Similarly, strings must be null terminated before iterating on a character array where the termination condition of the loop depends on the existence of a null-termination character within the memory allocated for the string, as in the following example:
Code Block | ||
---|---|---|
| ||
size_t i; char ntbs[16]; /* ... */ for (i = 0; i < sizeof(ntbs); ++i) { if (ntbs[i] == '\0') break; /* ... */ } |
...
Noncompliant Code Example (strncpy()
)
The standard {{ Wiki Markup strncpy()
}} function does not guarantee that the resulting string is null terminated \ [[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\]. If there is no null character in the first {{n
}} characters of the {{source
}} array, the result could not be null terminated.
In the first noncompliant code example, ntbs
is null terminated before the call to strncpy()
. However, the subsequent execution of strncpy()
can overwrite the null-termination character.
Code Block | ||||
---|---|---|---|---|
| ||||
char ntbs[NTBS_SIZE]; ntbs[sizeof(ntbs)-1] = '\0'; strncpy(ntbs, source, sizeof(ntbs)); |
In the second noncompliant code example, {{ Wiki Markup memset()
}} is used to clear the destination buffer; unfortunately, the third argument incorrectly specifies the size of the destination array \[ [Schwarz 2005|AA. Bibliography#Schwarz 05]\].
Code Block | ||||
---|---|---|---|---|
| ||||
char ntbs[NTBS_SIZE]; memset(ntbs, 0, sizeof(ntbs)-1); strncpy(ntbs, source, sizeof(ntbs)-1); |
...
Compliant Solution (strncpy_s()
)
The {{ Wiki Markup strncpy_s()
}} function copies up to {{n
}} characters from the source array to a destination array \ [[TR 24731|AA. Bibliography#ISO/IEC TR 24731-1-2007]\]. If no null character was copied from the source array, then the {{n
{}}}th position in the destination array is set to a null character, guaranteeing that the resulting string is null-terminated.
Code Block | ||||
---|---|---|---|---|
| ||||
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 */ } |
...
Tool | Version | Checker | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
|
| ||||||||||||
|
|
|
| ||||||||||||
|
|
|
|
Related Vulnerabilities
...
MITRE CWE: CWE-170, "Improper Null Termination"
Bibliography
...
\[[Schwarz 2005|AA. Bibliography#Schwarz 05]\]
\[[Seacord 2005a|AA. Bibliography#Seacord 05]\] Chapter 2, "Strings"
\[[Viega 2005|AA. Bibliography#Viega 05]\] Section ]
[Seacord 2005a] Chapter 2, "Strings"
[Viega 2005] Section 5.2.14, "Miscalculated NULL termination"
...
07. Characters and Strings (STR) STR33-C. Size wide character strings correctly