
Do not cast away a const
qualification on a variable type. Casting away the const
qualification allows violation of rule EXP31-C. Do not modify constant values prohibiting the modification of constant values.
Non-Compliant Code Example
The remove_spaces()
function in this non-compliant code example accepts a pointer to a string str
and a string length slen
and removes the space character from the string by shifting the remaining characters towards the front of the string. The function remove_spaces()
is passed a const
char
pointer as an argument. The const
qualification is cast away and then the contents of the string are modified.
void remove_spaces(char const *str, size_t slen) { char *p = (char*)str; size_t i; for (i = 0; i < slen && str[i]; i++) { if (str[i] != ' ') *p++ = str[i]; } *p = '\0'; }
Compliant Solution
In this compliant solution, the function remove_spaces()
is passed a non-const
char
pointer. The calling function must ensure that the NULL-terminated byte string passed to the function is not const
by making a copy of the string or by other means.
void remove_spaces(char *str, size_t slen) { char *p = str; size_t i; for (i = 0; i < slen && str[i]; i++) { if (str[i] != ' ') *p++ = str[i]; } *p = '\0'; }
Non-Compliant Code Example
In this non-compliant code example, the contents of the const
int
array vals
are cleared by the call to memset()
.
int const vals[] = {3, 4, 5}; memset(vals, 0, sizeof(vals));
Because the memset()
function takes a (non-const) pointer to void
, the compiler must implicitly cast away const
.
Implementation Details
The gcc
compiler issue a warning for cases such as this where an implicit cast is performed.
Compliant Solution
If the intention is to allow the array values to be modified, do not declare the array as const
.
int vals[] = {3, 4, 5}; memset(vals, 0, sizeof(vals));
Otherwise, do not attempt to modify the contents of the array.
Exceptions
EXP05-EX1: An exception to this rule is allowed when it is necessary to cast away const
when invoking a legacy API that does not accept a const
argument, provided the function does not attempt to modify the referenced variable. For example, the following code casts away the const
qualification of INVFNAME
in the call to the audit_log()
function.
void audit_log(char *errstr) { /* Legacy function defined elsewhere - cannot be modified */ fprintf(stderr, "Error: %s.\n", errstr); } /* ... */ char const INVFNAME[] = "Invalid file name."; audit_log((char *)INVFNAME); /* ... */
Risk Assessment
If the object is constant, the compiler may allocate storage in ROM or write-protected memory. Trying to modify such an object may lead to a program crash. This could allow an attacker to mount a denial-of-service attack.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP05-A |
low |
probable |
high |
P2 |
L3 |
Automated Detection
The LDRA tool suite V 7.6.0 is able to detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[ISO/IEC 9899-1999]] Section 6.7.3, "Type qualifiers"
[[ISO/IEC PDTR 24772]] "HFC Pointer casting and pointer type changes"
[[MISRA 04]] Rule 11.5
EXP04-A. Do not perform byte-by-byte comparisons between structures 03. Expressions (EXP) EXP06-A. Operands to the sizeof operator should not contain side effects