The C Standard, subclause 6.7.3, paragraph 6 [ISOISO/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.
...
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) Avoid casting away const qualification because doing so makes it easier to modify a const-qualified value without warningvalues without issuing diagnostics. See EXP05-C. Do not cast away a const qualification for more details.
Noncompliant Code Example
The following well-formed, but noncompliant code example borrowed from subclause , code example specified in subclause 6.5.16.1 of the C Standard allows a constant value to be modified:
| Code Block | ||||
|---|---|---|---|---|
| ||||
const char const **cpp; char *cpp; const char const c = 'A'; void func(void) { cpp = &cpp; /* Constraint violation */ *cpp = &c; /* Valid */ *cpp = 'B'0; /* 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 constness. 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.
| Code Block | ||||
|---|---|---|---|---|
| ||||
const char s[] = "foo";
int main() {
*(char*)s = '\0';
}
|
Implementation
...
Details
If cpp, cp p, and c are declared as automatic (stack) variables, this example compiles without warning on all versions of warning with Microsoft Visual Studio when 2012 when compiled in C mode (/TC) . In both cases, and the resulting program changes the value of c. GCC 3GCC 4.28.2 1 generates a warning but compiles. The , and the resulting program changes the value of c.
If cpp, cp p, and c are declared with static storage duration, this program terminates abnormally for both compiles without warning and terminates abnormally with Microsoft Visual Studio 2012, and compiles with warning and terminates abnormally with GCC 34.28.21.
Compliant Solution
The compliant solution depends on the intention intent of the programmer. If the intention intent is that the value of c is modifiable, then it should not be declared as a constant. If the intention , as in this compliant solution:
| Code Block | ||||
|---|---|---|---|---|
| ||||
char **cpp;
char *p;
char c = 'A';
void func(void) {
cpp = &p; /* Constraint violation */
*cpp = &c; /* Valid */
*p = 0; /* Valid */
} |
If the intent is that the value of c is not meant to change, then do not write noncompliant code that attempts to modify it. This may require relying on additional analysis tools to catch constraint violations in cases where the compiler does not emit a diagnostic.
Noncompliant Code Example
The following well-formed, but noncompliant, code example modifies a constant object after casting away its const qualifier.
| Code Block | ||||
|---|---|---|---|---|
| ||||
const char s[] = "foo";
void func(void) {
*(char *)s = '\0';
}
|
Compliant Solution
Similar to the previous compliant solution, this compliant solution depends on the intent of the programmer. If the intent is that s should be modifiable, then it should not be declared as a constant object. If the intent is that s should not be modifiable, then the explicit cast and assignment operations are erroneous and should be removed.
| Code Block | ||||
|---|---|---|---|---|
| ||||
char s[] = "foo";
void func(void) {
*s = '\0';
}
|
Risk Assessment
Modifying constant objects through nonconstant non-constant 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.
Related Guidelines
Bibliography
| [ISO/IEC 9899:2011] | Section Subclause 6.7.3, "Type Qualifiers" Subclause 6.5.16.1, "Simple assignment" |
...