Floating-point numbers can take on two classes of exceptional values; infinity and NaN (not-a-number). These values are returned as the result of exceptional or otherwise unresolvable floating point operations. (See also: FLP32-C. Prevent or detect domain and range errors in math functions). Additionally, they can be parsed from user input using Double.valueOf(Stirng s) or a similar method. Failure to detect and handle such values can result in undefined behavior.
NaN values are particularly problematic, as the expression NaN==NaN (for every possible value of NaN) returns false. Any comparisons made with NaN as one of the arguments returns false, and all arithmetic functions on NaNs simply propagate them through the code. Hence, a NaN entered in one location in the code and not properly handled could potentially cause problems in other, more distant sections.
Double.valueOf(String s) can return NaN or an infinite double as normal operation. Programs should therefore check to ensure that all input floating point values (especially those controlled by the user) do not have either of these values if doing so would be inappropriate. Double.isNaN(double d) and Double.isInfinite(double d) can be used to do the appropriate testing.
Noncompliant Code Example
The following noncompliant code accepts user data without first validating it.
double currentBalance; /* User's cash balance */ void doDeposit(String userInput){ double val; try { val = Double.valueOf(userInput); } catch(NumberFormatException e) { /*Handle input format error*/ } if(val>=MAX_VALUE-currentBalance) { /*Handle range error*/ } currentBalance+=val; }
This can be a problem if an invalid value is entered for val and subsequently used for calculations or as control values. The user could, for example, input the strings "Infinity" or "NaN" on the command line, which would be parsed by Double.valueOf(String s) into the floating-point representations of infinity and NaN. All subsequent calculations using these values would be invalid, possibly crashing the program and enabling a DOS attack.
Here, for example, entering "NaN" for val would force currentBalance to also equal "NaN", corrupting its value. If this value is used elsewhere for calculations, every resulting value would also be NaN, possibly destroying important data.
Compliant Code Example
The following code first validates the input float before using it. The value is tested to ensure that it is neither infinity nor negative infinity nor NaN.
double currentBalance; /* User's cash balance */ void doDeposit(String s){ double val; try { val = Double.valueOf(userInput); } catch(NumberFormatException e) { /*Handle input format error*/ } if (Double.isInfinite(val)){ /* handle infinity error */ } if (Double.isNaN(val)){ /* handle NaN error */ } if(val>=MAX_VALUE-currentBalance) { /*Handle range error*/ } currentBalance+=val; }
Exceptions
Occasionally, NaN or infinity may be acceptable or expected inputs to a program. If this is the case, then explicit checks may not be necessary. Such programs must, however, be prepared to handle these inputs gracefully and not blindly use them in mathematical expressions where they are not appropriate.
Risk Assessment
Inappropriate floating point inputs can result in invalid calculations and unexpected results, possibly leading to crashing and providing a DOS opportunity.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FLP04-C. |
low |
probable |
high |
P6 |
L2 |
Automated Detection
TODO
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 FLP04-C. Check floating point inputs for exceptional values