Platform dependencies may be introduced to improve performance on a particular platform. This can be a dangerous practice, particularly if these dependencies are not appropriately documented during development and addressed during porting. Platform dependencies that have no performance or other benefits should consequently be avoided as they may introduce errors during porting.
The C99 standard identifies two different kinds of non-portable behavior, implementation-defined and unspecified.
C99 Section 3.4.1 defines implementation-defined behavior as:
unspecified behavior where each implementation documents how the choice is made
An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.
C99 Section 3.4.4 defines unspecified behavior as:
use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance
An example of unspecified behavior is the order in which the arguments to a function are evaluated.
Appendix J.1, "Unspecified behavior" provides a list of unspecified behaviors in C99, and Appendix J.3, "Implementation-defined behavior" provides a list of implementation-defined behaviors in C99.
Most legitimate platform dependencies can and should be isolated in separate modules that use portable interfaces but platform-specific implementations.
Non-Compliant Code Example
This non-compliant code example uses the complement operator in the test for unsigned integer overflow.
unsigned int ui1, ui2, sum; if (~ui1 < ui2) { /* handle error condition */ } sum = ui1 + ui2;
This code assumes that the implementation uses two's complement representation. This assumption is commonly true, but not guaranteed by the standard.
This solution also violates INT14-A. Avoid performing bitwise and arithmetic operations on the same data.
Compliant Solution
This compliant solution implements a strictly conforming test for unsigned overflow.
unsigned int ui1, ui2, sum; if (UINT_MAX - ui1 < ui2) { /* handle error condition */ } sum = ui1 + ui2;
If the non-compliant form of this test is truly faster, talk to your compiler vendor, because if these tests are equivalent then optimization should occur. If both forms have the same performance, prefer the portable form.
Risk Assessment
Unnecessary platform dependencies are, by definition, unnecessary. Avoiding these dependencies can eliminate porting errors resulting from invalidated assumptions.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC14-A |
low |
unlikely |
medium |
P2 |
L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Dowd 06]] Chapter 6, "C Language Issues" (Arithmetic Boundary Conditions, pp. 211-223)
[[ISO/IEC 9899-1999]] Section 3.4.1, "implementation-defined behavior", Section 3.4.4, "unspecified behavior", Appendix J.1, "Unspecified behavior", Appendix J.3, "Implementation-defined behavior"
[[ISO/IEC PDTR 24772]] "BQF Unspecified Behaviour"
[[Seacord 05]] Chapter 5, "Integers"
MSC13-A. Detect and remove unused values 13. Miscellaneous (MSC) MSC15-A. Do not depend on undefined behavior