Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changed title & gist to follow title

Do not cast away a volatile qualification on a variable type. Casting away the volatile qualification permits the compiler to optimize away operations on the volatile type, thereby negating the use of the volatile keyword in the first place.

Wiki Markup
According to C99 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.3, "Type qualifiers," Paragraph 5:

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.

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.

Non-Compliant Code Example

In this example, a volatile object is accessed through a non-volatile-qualified reference, resulting in undefined behavior.

Code Block
bgColor#FFcccc
static volatile int **ipp;
static int *ip;
static volatile int i = 0;

printf("i = %d.\n", i);

ipp = &ip; /* produces warnings in modern compilers */
ipp = (int**) &ip; /* constraint violation */
*ipp = &i; /* valid */
if (*ip != 0) { /* valid */
  /* ... */
}

The assignment ipp = &ip is unsafe because it would allow 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 it is not possible that i != 0 if i is not volatile.

Implementation Details

This example compiles without warning on Microsoft Visual C++ .NET (2003) and on MS Visual Studio 2005. 

...

Version 3.2.2 and Version 4.1.3 of the GCC compiler generate a warning, but they compile.

Compliant Solution

In this compliant solution, ip is declared as volatile.

Code Block
bgColor#ccccff
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 a volatile Casting away volatile allows one to access a object through a non-volatile reference. This can result in undefined and perhaps unintended program behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP32-C

1 (low)

3 (likely)

2 (medium)

P6

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[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"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "HFC Pointer casting and pointer type changes"
\[[MISRA 04|AA. C References#MISRA 04]\] Rule 11.5

...