A string literal is a sequence of zero or more multibyte characters enclosed in double quotes ("xyz"
, for example). A wide string literal is the same, except prefixed by the letter 'L' (L"xyz"
, for example).
At compile time, string literals are used to create an array of static storage duration of sufficient length to contain the character sequence and a null-termination character. It is unspecified whether these arrays are distinct. The behavior is undefined if a program attempts to modify string literals but frequently results in an access violation, as string literals are typically stored in read-only memory. See also undefined behavior 30 of Annex J of C99.
Do not attempt to modify a string literal. Use a named array of characters to obtain a modifiable string.
Noncompliant Code Example
In this noncompliant code example, the char
pointer p
is initialized to the address of a string literal. Attempting to modify the string literal results in undefined behavior.
char *p = "string literal"; p[0] = 'S';
Compliant Solution
As an array initializer, a string literal specifies the initial values of characters in an array as well as the size of the array. (See guideline STR36-C. Do not specify the bound of a character array initialized with a string literal.) This code creates a copy of the string literal in the space allocated to the character array a
. The string stored in a
can be safely modified.
char a[] = "string literal"; a[0] = 'S';
Noncompliant Code Example
In this noncompliant example, the mktemp()
function modifies its string argument.
char *fname; fname = mktemp("/tmp/edXXXXXX");
Compliant Solution
Instead of passing a string literal, use a named array:
static char fname[] = "/tmp/edXXXXXX"; mktemp(fname);
Noncompliant Code Example (Result of strrchr()
)
In this noncompliant example, the non-const char*
result of the strchr()
function is used to modify the object pointed to by pathname
. Since the pointer points to a string literal the effects of the modification are undefined and are likely to cause a signal such as SIGSEGV
to be generated for the process if the object is stored in read-only memory.
const char* get_dirname(const char* pathname) { char* slash; slash = strrchr(pathname, '/'); if (slash) *slash = '\0'; /* undefined behavior */ return pathname; } int main() { puts(get_dirname(__FILE__)); return 0; }
Compliant Solution (Result of strrchr()
)
A compliant solution avoids modifying a const object, even if it is possible to obtain a non-const pointer to such an object by calling a standard C library function such as strrchr()
. To reduce the risk of callers of get_dirname()
passing constant objects to the function the argument is declared to be a non-const pointer. While converting a string literal to non-const char*
is permitted by the language conforming compilers may issue a diagnostic for such code. See also guideline EXP05-C. Do not cast away a const qualification.
char* get_dirname(char* pathname) { char* slash; slash = strrchr(pathname, '/'); if (slash) *slash = '\0'; return pathname; } int main() { char pathname[] = __FILE__; /* calling get_dirname(__FILE__) may be diagnosed */ puts(get_dirname(pathname)); return 0; }
Risk Assessment
Modifying string literals can lead to abnormal program termination and possibly denial-of-service attacks.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
STR30-C |
low |
likely |
low |
P9 |
L2 |
Automated Detection
Tool |
Version |
Checker |
Description |
---|---|---|---|
9.7.1 |
|
|
|
Splint |
3.1.1 |
|
|
Compass/ROSE |
|
|
can detect simple violations of this rule |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
C++ Secure Coding Standard: STR30-CPP. Do not attempt to modify string literals
Bibliography
[ISO/IEC 9899:1999] Section 6.4.5, "String literals"
[Summit 1995] comp.lang.c FAQ list - Question 1.32
[Plum 1991] Topic 1.26, "strings - string literals"
STR11-C. Use expression containing sizeof operator to calculate the length of an array 07. Characters and Strings (STR)