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 strcpy()
or strlen()
. These functions, as well as other string-handling functions defined by the C Standard [ISO/IEC 9899:2011]Standard, 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 | ||||
---|---|---|---|---|
| ||||
#include <string.h> enum { NTBS_SIZE = 32 }; void func(const char *source) { char ntbs[NTBS_SIZE]; if (source) { if (strlen(source) < sizeof(ntbs)) { strcpy(ntbs, source); } else { /* Handle string -too -large condition. */ } } 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 [ISO/IEC 9899:2011]. 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 | ||||
---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__
#include <string.h>
enum { NTBS_SIZE = 32 };
void func(const 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. */
}
} |
Noncompliant Code Example (realloc()
)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h>
char *cur_msg = NULL;
size_t cur_msg_size = 1024;
void lessen_memory_usage(void) {
char *temp;
size_t temp_size;
if (cur_msg != NULL) {
temp_size = cur_msg_size / 2 + 1;
temp = realloc(cur_msg, temp_size);
if (temp == NULL) {
/* Handle error */
}
cur_msg = temp;
cur_msg_size = temp_size;
/* Ensure string is null-terminated. */
cur_msg[cur_msg_size - 1] = '\0';
}
} |
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
STR32-C | highHigh | probableProbable | mediumMedium | P12 | L1 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
|
| Can detect some violations of this rule | |||||||
Coverity | 6.5 | STRING_NULL | Fully Implemented | ||||||
| NNTS |
| |||||||
| 600 S | Fully implemented |
...
CERT C++ Secure Coding Standard | STR32-CPP. Null-terminate character arrays as required |
ISO/IEC TR 24772:2013 | String Termination [CMJ] |
ISO/IEC TS 17961 (Draft) | Passing a non-null-terminated character sequence to a library function that expects a string [strmod] |
MITRE CWE | CWE-119, Failure to constrain operations within the bounds of an allocated memory buffer CWE-170, Improper null termination |
Bibliography
...
[Seacord 2013] | Chapter 2, "Strings" |
[Viega 2005] | Section 5.2.14, "Miscalculated NULL Termination" |
...