An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. It is possible to reference Referencing a volatile object by using a non-volatile value, but the resulting behavior lvalue is undefined . According to C99 Section behavior. The C Standard, 6.7.3, "Type qualifiers," Paragraph 5:4 paragraph 7 [ISO/IEC 9899:2024], states
If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.
Noncompliant Code Example
In this noncompliant code example, a volatile object is accessed through a non-volatile-qualified reference, resulting in undefined behavior:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> void func(void) { static volatile int **ipp; static int *ip; static volatile int i = 0; printf("i = %d.\n", i); ipp = &ip; /* May produce a warning diagnostic */ ipp = (int**) &ip; /* Constraint violation; may produce a warning diagnostic */ *ipp = &i; /* Valid */ if (*ip != 0) { /* Valid */ /* . |
...
.. */
}
} |
The assignment ipp = &ip
is not safe because it allows the valid code that follows to reference the value of the volatile object i
through the non-volatile-qualified reference ip
. In this example, the compiler may optimize out the entire if
block because *ip != 0
must be false if the object to which ip
points is not volatile.
Implementation Details
This example compiles without warning on Microsoft Visual Studio 2013 when compiled in C mode (/TC
) but causes errors when compiled in C++ mode (/TP
).
GCC 4.8.1 generates a warning but compiles successfully.
Compliant Solution
In this compliant solution, ip
is declared volatile
:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h>
void func(void) {
static volatile int **ipp;
static volatile int *ip;
static volatile int i = 0;
printf("i = %d.\n", i);
ipp = &ip;
*ipp = &i;
if (*ip != 0) {
/* ... */
}
} |
Risk Assessment
Accessing an object with a volatile-qualified type through a reference with a non-volatile-qualified type is
This also applies to objects that behave as if they were defined with qualified types, such as an object at a memory-mapped input/output address.
...
Risk Assessment
Accessing a volatile object through a non-volatile reference results in undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP32-C |
1 (low)
3 (unlikely)
2 (medium)
P6
L2
Low | Likely | Medium | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| pointer-qualifier-cast-volatile pointer-qualifier-cast-volatile-implicit | Supported indirectly via MISRA C 2012 Rule 11.8 | ||||||
Axivion Bauhaus Suite |
| CertC-EXP32 | Fully implemented | ||||||
Clang |
| -Wincompatible-pointer-types-discards-qualifiers | |||||||
Compass/ROSE | |||||||||
Coverity |
| MISRA C 2012 Rule 11.8 | Implemented | ||||||
Cppcheck Premium |
| premium-cert-exp32-c | Partially implemented | ||||||
GCC |
| Can detect violations of this rule when the | |||||||
Helix QAC |
| C0312, C0562, C0563, C0673, C0674 | Fully implemented | ||||||
Klocwork |
| CERT.EXPR.VOLATILE.ADDR | Fully implemented | ||||||
LDRA tool suite |
| 344 S | Partially implemented | ||||||
Parasoft C/C++test |
| CERT_C-EXP32-a | A cast shall not remove any 'const' or 'volatile' qualification from the type of a pointer or reference | ||||||
Polyspace Bug Finder |
| Checks for cast to pointer that removes const or volatile qualification (rule fully covered) | |||||||
RuleChecker |
| pointer-qualifier-cast-volatile pointer-qualifier-cast-volatile-implicit | Supported indirectly via MISRA C 2012 Rule 11.8 |
Related Vulnerabilities
Search for Examples of vulnerabilities resulting from the violation of this rule can be found on the CERTwebsite.
References
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
ISO/IEC TR 24772:2013 | Pointer Casting and Pointer Type Changes [HFC] | Prior to 2018-01-12: CERT: Unspecified Relationship |
ISO/IEC TR 24772:2013 | Type System [IHN] | Prior to 2018-01-12: CERT: Unspecified Relationship |
MISRA C:2012 | Rule 11.8 (required) | Prior to 2018-01-12: CERT: Unspecified Relationship |
CERT C | EXP55-CPP. Do not access a cv-qualified object through a cv-unqualified type | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
[ISO/IEC 9899:2024] | 6.7.4, "Type Qualifiers" |
...
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]] Section 6.7.3, "Type qualifiers," and Section 6.5.16.1, "Simple assignment" Wiki Markup