You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Floating-point numbers can take on two kinds of exceptional values, infinity and NaN (not-a-number). These values are produced as a result of exceptional or otherwise unresolvable floating point operations. Additionally, they can be obtained directly from user input through the aid of methods like Double.valueOf(String s). Failure to detect and handle such values can result in inconsistent behavior.

NaN values are particularly problematic, as the expression NaN == NaN always returns false (See FLP02-J. Do not attempt comparisons with NaN). In general, any comparisons made with NaN return false, and all arithmetic functions on NaN inputs simply propagate the taint throughout the code. Hence, just one occurrence of a NaN value can effectuate negative repercussions within other code segments.

The method Double.valueOf(String s) can return NaN or an infinite double as specified by its contract. Programs should install checks to ensure that all floating point inputs (especially those obtained from the user) do not contain either of these values before proceeding to operate on them. The methods Double.isNaN(double d) and Double.isInfinite(double d) can be used for this purpose.

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 >= Double.MAX_VALUE - currentBalance) {
    /*Handle range error*/
  }

  currentBalance+=val;
}

This can be a problem if an invalid value is entered for val and subsequently used in 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 either infinity or 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 in other expressions, every resulting value would also be NaN, possibly destroying important data.

Compliant Code Example

The following code first validates the floating point input before using it. The value is tested to ensure that it is neither infinity, 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 >= Double.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 should not allow the propagation of taint to other values when using them in mathematical expressions where they are inappropriate.

Risk Assessment

Incorrect or missing validation of floating point inputs can result in miscalculations and unexpected results, possibly leading to inconsistent program behavior and denial of service (DoS).

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FLP04-J.

low

probable

medium

P4

L3

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

References

[IEEE 754]
[IEEE 1003.1, 2004]

  • No labels