You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: c/cert/src/rules/EXP32-C/DoNotAccessVolatileObjectWithNonVolatileReference.md
+90-3Lines changed: 90 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,13 +5,100 @@ This query implements the CERT-C rule EXP32-C:
5
5
> Do not access a volatile object through a nonvolatile reference
6
6
7
7
8
-
## CERT
9
8
10
-
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py`**
9
+
## Description
10
+
11
+
An object that has volatile-qualified type may be modified in ways unknown to the [implementation](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) or have other unknown [side effects](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-sideeffect). Referencing a volatile object by using a non-volatile lvalue is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior). The C Standard, 6.7.3 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], states
12
+
13
+
> 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.
14
+
15
+
16
+
See [undefined behavior 65](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_65).
17
+
18
+
## Noncompliant Code Example
19
+
20
+
In this noncompliant code example, a volatile object is accessed through a non-volatile-qualified reference, resulting in [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior):
21
+
22
+
```cpp
23
+
#include<stdio.h>
24
+
25
+
voidfunc(void) {
26
+
static volatile int **ipp;
27
+
static int *ip;
28
+
static volatile int i = 0;
29
+
30
+
printf("i = %d.\n", i);
31
+
32
+
ipp = &ip; /* May produce a warning diagnostic */
33
+
ipp = (int**) &ip; /* Constraint violation; may produce a warning diagnostic */
34
+
*ipp = &i; /* Valid */
35
+
if (*ip != 0) { /* Valid */
36
+
/* ... */
37
+
}
38
+
}
39
+
```
40
+
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.
41
+
42
+
**Implementation Details**
43
+
44
+
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`).
45
+
46
+
GCC 4.8.1 generates a warning but compiles successfully.
47
+
48
+
## Compliant Solution
49
+
50
+
In this compliant solution, `ip` is declared `volatile`:
51
+
52
+
```cpp
53
+
#include <stdio.h>
54
+
55
+
void func(void) {
56
+
static volatile int **ipp;
57
+
static volatile int *ip;
58
+
static volatile int i = 0;
59
+
60
+
printf("i = %d.\n", i);
61
+
62
+
ipp = &ip;
63
+
*ipp = &i;
64
+
if (*ip != 0) {
65
+
/* ... */
66
+
}
67
+
68
+
}
69
+
```
70
+
71
+
## Risk Assessment
72
+
73
+
Accessing an object with a volatile-qualified type through a reference with a non-volatile-qualified type is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior).
<table> <tbody> <tr> <th> Tool </th> <th> Version </th> <th> Checker </th> <th> Description </th> </tr> <tr> <td> <a> Astrée </a> </td> <td> 22.04 </td> <td> <strong>pointer-qualifier-cast-volatile</strong> <strong>pointer-qualifier-cast-volatile-implicit</strong> </td> <td> Supported indirectly via MISRA C 2012 Rule 11.8 </td> </tr> <tr> <td> <a> Axivion Bauhaus Suite </a> </td> <td> 7.2.0 </td> <td> <strong>CertC-EXP32</strong> </td> <td> Fully implemented </td> </tr> <tr> <td> <a> Clang </a> </td> <td> 3.9 </td> <td> <code>-Wincompatible-pointer-types-discards-qualifiers</code> </td> <td> </td> </tr> <tr> <td> <a> Compass/ROSE </a> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> <a> Coverity </a> </td> <td> 2017.07 </td> <td> <strong>MISRA C 2012 Rule 11.8</strong> </td> <td> Implemented </td> </tr> <tr> <td> <a> GCC </a> </td> <td> 4.3.5 </td> <td> </td> <td> Can detect violations of this rule when the <code>-Wcast-qual</code> flag is used </td> </tr> <tr> <td> <a> Helix QAC </a> </td> <td> 2022.4 </td> <td> <strong>C0312, C0562, C0563, C0673, C0674</strong> </td> <td> </td> </tr> <tr> <td> <a> Klocwork </a> </td> <td> 2022.4 </td> <td> <strong>CERT.EXPR.VOLATILE.ADDR</strong> <strong>CERT.EXPR.VOLATILE.ADDR.PARAM</strong> <strong>CERT.EXPR.VOLATILE.PTRPTR</strong> </td> <td> </td> </tr> <tr> <td> <a> LDRA tool suite </a> </td> <td> 9.7.1 </td> <td> <strong>344 S</strong> </td> <td> Partially implemented </td> </tr> <tr> <td> <a> Parasoft C/C++test </a> </td> <td> 2022.2 </td> <td> <strong>CERT_C-EXP32-a</strong> </td> <td> A cast shall not remove any 'const' or 'volatile' qualification from the type of a pointer or reference </td> </tr> <tr> <td> <a> Polyspace Bug Finder </a> </td> <td> </td> <td> <a> CERT C: Rule EXP32-C </a> </td> <td> Checks for cast to pointer that removes const or volatile qualification (rule fully covered) </td> </tr> <tr> <td> <a> PRQA QA-C </a> </td> <td> 9.7 </td> <td> <strong>0312,562,563,673,674</strong> </td> <td> Fully implemented </td> </tr> <tr> <td> <a> RuleChecker </a> </td> <td> 22.04 </td> <td> <strong>pointer-qualifier-cast-volatile</strong> <strong>pointer-qualifier-cast-volatile-implicit</strong> </td> <td> Supported indirectly via MISRA C 2012 Rule 11.8 </td> </tr> </tbody> </table>
81
+
82
+
83
+
## Related Vulnerabilities
84
+
85
+
Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+EXP32-C).
86
+
87
+
## Related Guidelines
88
+
89
+
[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions)
90
+
91
+
<table> <tbody> <tr> <th> Taxonomy </th> <th> Taxonomy item </th> <th> Relationship </th> </tr> <tr> <td> <a> ISO/IEC TR 24772:2013 </a> </td> <td> Pointer Casting and Pointer Type Changes \[HFC\] </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> <tr> <td> <a> ISO/IEC TR 24772:2013 </a> </td> <td> Type System \[IHN\] </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> <tr> <td> <a> MISRA C:2012 </a> </td> <td> Rule 11.8 (required) </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> <tr> <td> <a> CERT C </a> </td> <td> <a> EXP55-CPP. Do not access a cv-qualified object through a cv-unqualified type </a> </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> </tbody> </table>
In limited cases, this query can raise false-positives for assignment of volatile objects and subsequent accesses of those objects via non-volatile pointers.
0 commit comments