
The C Standard, subclause 6.7.3, paragraph 6 [ISO/IEC 9899:2011], states:
If an attempt is made to modify an object defined with a
const
-qualified type through use of an lvalue with non-const
-qualified type, the behavior is undefined.
(See also undefined behavior 64 in Appendix J of the C Standard.)
There are existing compiler implementations that allow const
-qualified values to be modified without generating a warning message.
It is also a recommended practice not to cast away a const
qualification (as in EXP05-C. Do not cast away a const qualification) because doing so makes it easier to modify a const
-qualified value without warning.
Noncompliant Code Example
The following well-formed but noncompliant code example borrowed from subclause 6.5.16.1 of the C Standard allows a constant value to be modified:
char const **cpp; char *cp; char const c = 'A'; cpp = &cp; /* Constraint violation */ *cpp = &c; /* Valid */ *cp = 'B'; /* Valid */
The first assignment is unsafe because it would allow the valid code that follows to attempt to change the value of the const
object c
.
Noncompliant Code Example (Modifying a String Literal)
Similarly to the previous example, the following well-formed but noncompliant code example modifies a constant object after casting away its const
ness. Compiling the program on a Linux/x64 system does not produce any diagnostics even at high warning levels, but the generated executable program fails at runtime with SIGESGV
.
const char s[] = "foo"; int main() { *(char*)s = '\0'; }
Implementation-Specific Details
If cpp
, cp
, and c
are declared as automatic (stack) variables, this example compiles without warning on all versions of Microsoft Visual Studio when compiled in C mode (/TC). In both cases, the resulting program changes the value of c
. GCC 3.2.2 generates a warning but compiles. The resulting program changes the value of c
.
If cpp
, cp
, and c
are declared with static storage duration, this program terminates abnormally for both Microsoft Visual Studio and GCC 3.2.2.
Compliant Solution
The compliant solution depends on the intention of the programmer. If the intention is that the value of c
is modifiable, then it should not be declared as a constant. If the intention is that the value of c
is not meant to change, then do not write noncompliant code that attempts to modify it.
Risk Assessment
Modifying constant objects through nonconstant references results in undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP40-C | low | unlikely | medium | P2 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Bibliography
[ISO/IEC 9899:2011] | Section 6.7.3, "Type Qualifiers" |