The sizeof
operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. When the type of the operand is a variable-length array type (VLA) the expression is evaluated; otherwise the operand is not evaluated.
When part of the operand of the sizeof
operator is a VLA type and when changing the value of the VLA's size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated. See unspecified behavior 21 in section J.1 of C99.
Providing an expression that appears to produce side effects may be misleading to programmers who are not aware that these expressions are not evaluated in the non-VLA case and has unspecified results otherwise. As a result, programmers may make invalid assumptions about program state, leading to errors and possible software vulnerabilities.
Noncompliant Code Example
In this noncompliant code example, the expression a++
is not evaluated and the side effects in the expression are not executed.
int a = 14; int b = sizeof(a++);
Consequently, the value of a
after b
has been initialized is 14.
Implementation-Specific Details
This example compiles cleanly under Microsoft Visual Studio 2005 Version 8.0, with the /W4 option.
Compliant Solution
In this compliant solution, the variable a
is incremented.
int a = 14; int b = sizeof(a); a++;
Noncompliant Code Example (Variable Length Array)
In the following noncompliant code example the expression ++n
in the initialization expression of a
must be evaluated since its value affects the size of the variable length array operand of the sizeof
operator. However, since the expression ++n % 1
evaluates to 0
regardless of the value of n
its value does not affect the result of the sizeof
operator and thus it is unspecified whether n
is incremented or not.
void f(size_t n) { size_t a = sizeof(int [++n]); /* n must be incremented */ size_t b = sizeof(int [++n % 1 + 1]); /* n need not be incremented */ /* ... */ }
Compliant Solution (Variable Length Array)
The compliant solution below avoids changing the value of the variable n
used in the sizeof
expression and instead increments it safely outside of it.
void f(size_t n) { size_t a = sizeof(int [n + 1]); ++n; size_t b = sizeof(int [n % 1 + 1]); ++n; /* ... */ }
Risk Assessment
If expressions that appear to produce side effects are supplied to the sizeof
operator, the returned result may be different than expected. Depending on how this result is used, this can lead to unintended program behavior.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP06-C |
low |
unlikely |
low |
P3 |
L3 |
Automated Detection
The LDRA tool suite V 7.6.0 can detect violations of this recommendation.
Compass/ROSE can detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as EXP06-CPP. Operands to the sizeof operator should not contain side effects.
References
[[ISO/IEC 9899:1999]] Section 6.5.3.4, "The sizeof operator"