According to the C Standard, 6.4.5, paragraph 3 [ISO/IEC 9899:20112024]:
A A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in "xyz". A UTF−8 UTF-8 string literal is the same, except prefixed by u8. A wide wchar_t string literal is the same, except prefixed by the letter L
, u
, or U
.L. A UTF-16 string literal is the same, except prefixed by u. A UTF-32 string literal is the same, except prefixed by U. Collectively, wchar_t, UTF-16, and UTF-32 string literals are called wide string literals.
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 terminating null character. String literals are usually referred to by a pointer to (or array of) characters. Ideally, they should be assigned only to pointers to (or arrays of) const char
or const wchar_t
. It is unspecified whether these arrays of string literals are distinct from each other. The behavior is undefined if a program attempts to modify any portion of a string literal. Modifying a string literal frequently results in an access violation because string literals are typically stored in read-only memory. (See undefined behavior 33.)
...
In this noncompliant code example, the char
pointer p
is str
is initialized to the address of a string literal. Attempting to modify the string literal is undefined behavior:
Code Block |
---|
|
char *pstr = "string literal";
pstr[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 STR11-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
str
. The string stored in a
can str
can be modified safely.
Code Block |
---|
|
char astr[] = "string literal";
astr[0] = 'S';
|
Noncompliant Code Example (POSIX)
...
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 |
---|
Astrée | |
CERT.PRE.32 | string-literal-modfication write-to-string-literal | Fully checked |
Axivion Bauhaus Suite | Include Page |
---|
| Axivion Bauhaus Suite_V |
---|
| Axivion Bauhaus Suite_V |
---|
|
| CertC-STR30 | Fully implemented |
Fully checked | |
|
| Can detect simple violations of this rule |
Coverity | | PW | Deprecates conversion from a string literal to "char *" |
Helix QAC | | C0556, C0752, C0753, C0754 C++3063, C++3064, C++3605, C++3606, C++3607 |
|
Klocwork | | CERT.STR.ARG.CONST_TO_NONCONST CERT.STR.ASSIGN.CONST_TO_NONCONST |
|
LDRA tool suite | | 157 S | Partially implemented |
Parasoft C/C++test |
9.5 | PB-27 | | | CERT_C-STR30-a CERT_C-STR30-b | A string literal shall not be modified Do not modify string literals |
PC-lint Plus | Include Page |
---|
| PC-lint Plus_V |
---|
| PC-lint Plus_V |
---|
|
| 489, 1776 | Partially supported |
Polyspace Bug Finder | |
R2016a | Writing to const qualified object |
Object declared with a const qualifier is modified | PRQA QA-CPRQA QACvPRQA QAC_v0556 0752 0753 | | V675 |
|
RuleChecker | Include Page |
---|
| RuleChecker_V |
---|
| RuleChecker_V |
---|
|
| string-literal-modfication | Partially checked |
Partially implemented | PRQA QA-C++ | 4.2 | 3063, 3064, 3605, 3606, 3607, 3842 | 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)
Bibliography
20112024] | 6.4.5, "String Literals" |
[Plum 1991] | Topic 1.26, "Strings—String Literals" |
[Summit 1995] | comp.lang.c FAQ List, Question 1.32 |
...
Image Modified Image Modified Image Modified