Errors during floating-point operations are often neglected by programmers who instead focus on validating operands before an operation. Errors occurring that occur during floating-point operations are admittedly difficult to determine and diagnose, but the benefits of doing so often outweigh the costs. This recommendation suggests ways to capture errors during floating-point operations.
...
- Conversion from floating-point to integer may cause an "invalid" floating-point exception. If this occurs, the value of that integer is undefined and should not be used.
- Most implementations fail to raise "invalid" for conversions from any negative or "large" positive floating-point values to unsigned integer types or to
signed char
. (See tflt2int.c.) - When a noninteger floating-point value is converted to an integer, the "inexact" floating-point exception is raised.
...
A less portable but potentially more secure solution is to use the capabilities provided by the underlying implementation. If this approach is taken, the caveats of that system must be well understood. The following table provides a starting point for some common operating systems:
Operating System | How to Handle Floating-Point Errors |
---|---|
Linux | Use the C floating-point exception functions |
Windows | Use either the C floating-point exception functions or structured exception handling through |
Noncompliant Code Example
...
Code Block | ||||
---|---|---|---|---|
| ||||
void fp_usingSEH(void) { /* ... */ double a = 1e-40, b, c = 0.1; float x = 0, y; unsigned int rv ; unmask_fpsr(); _try { /* Store into y is inexact and underflows: */ y = a; /* Divide-by-zero operation */ b = y / x; /* Inexact */ c = sin(30) * a; } _except (_fpieee_flt( GetExceptionCode(), GetExceptionInformation(), fpieee_handler)) { { printf ("fpieee_handler: EXCEPTION_EXECUTE_HANDLER"); } /* ... */ } void unmask_fpsr(void) { unsigned int u; unsigned int control_word; _controlfp_s(&control_word, 0, 0); u = control_word & ~(_EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT); _controlfp_s( &control_word, u, _MCW_EM); return ; } int fpieee_handler(_FPIEEE_RECORD *ieee) { /* ... */ switch (ieee->RoundingMode) { case _FpRoundNearest: /* ... */ break; /* * Other RMs include _FpRoundMinusInfinity, * _FpRoundPlusInfinity, _FpRoundChopped. */ /* ... */ } switch (ieee->Precision) { case _FpPrecision24: /* ... */ break; /* Other Ps include _FpPrecision53 */ /* ... */ } switch (ieee->Operation) { case _FpCodeAdd: /* ... */ break; /* * Other Ops include _FpCodeSubtract, _FpCodeMultiply, * _FpCodeDivide, _FpCodeSquareRoot, _FpCodeCompare, * _FpCodeConvert, _FpCodeConvertTrunc. */ /* ... */ } /* * Process the bitmap ieee->Cause. * Process the bitmap ieee->Enable. * Process the bitmap ieee->Status. * Process the Operand ieee->Operand1, * evaluate format and Value. * Process the Operand ieee->Operand2, * evaluate format and Value. * Process the Result ieee->Result, * evaluate format and Value. * The result should be set according to the operation * specified in ieee->Cause and the result formatted as * specified in ieee->Result. */ /* ... */ } |
...
Undetected floating-point errors may result in lower program efficiency, inaccurate results, or software vulnerabilities. Most processors stall for a significant duration (sometimes up to a second or even more on 32-bit desktop processors) when an operation incurs a NaN (not a number) when an operation incurs a NaN (not a number) value.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FLP03-C |
Low |
Probable |
High | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| float-division-by-zero | Partially checked | ||||||
Compass/ROSE |
Could detect violations of this rule by ensuring that floating-point operations are surrounded by |
LDRA tool suite |
| 43 D | Partially implemented | ||||||
Parasoft C/C++test |
|
|
|
4123
4124
4125
4126
4127
4128
CERT_C-FLP03-a | Avoid division by zero | ||||||||
Parasoft Insure++ | Runtime analysis | ||||||||
PC-lint Plus |
| 736, 9120, 9227 | Assistance provided | ||||||
Polyspace Bug Finder |
| Checks for:
Rec. partially covered. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this recommendation on the CERT website.
Related Guidelines
SEI CERT C++ |
Coding Standard | VOID FLP03-CPP. Detect and handle floating point errors |
MITRE CWE | CWE-369, Divide by zero |
Bibliography
[IEEE |
Std 1003.1:2013] |
XBD, Headers, <fenv.h> |
[Intel 2001] |
[ISO/IEC 9899:2011] | Subclause 7.6.2, "Floating-Point Exceptions" |
[Keil 2008] |
[MSDN] | "fpieee_flt (CRT) |
fenv.h
- Floating-point environment" |
[SecurityFocus 2007] |
...
...