...
If infinity or NaN values are not acceptable inputs in a program, these macros should be used to ensure they are not passed to vulnerable functions.
Implementation Details
If an out of range float is entered into a formatted input function, it is automatically converted by the function into infinity if it is greater than FLOAT_MAX, or to negative infinity if it is less than FLOAT_MIN. Thus users can still force a float to be infinity, even if their input strings are tested for the "inf" or "infinity" pattern. The exact values of FLOAT_MIN and FLOAT_MAX are implementation specific.
For example, if FLOAT_MAX is 1e99, then passing the string "1e9999" to scanf("%f", &x) will result in x having the value infinity.
Therefore, any floating-point input should be tested for infinity or nan, even if the text strings are filtered.
Noncompliant Code Example
The following noncompliant code accepts user data without first validating it.
Code Block | ||
---|---|---|
| ||
doublefloat currentBalance; /* User's cash balance */ void doDeposit(){ doublefloat val; scanf("%g%f", &val); if(val>=MAX_VALUE-currentBalance) { /*Handle range error*/ } currentBalance+=val; } |
...
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.
Implementation Details
The following code was run on GNU Linux using the GCC compiler. On this platform, FLT_MAX has the value 340282346638528859811704183484516925440.000000. FLT_MIN=-FLT_MAX.
Code Block |
---|
#include <stdio.h>
int main(int argc, char *argv[])
{
float val, currentBalance=0;
scanf("%f", &val);
currentBalance+=val;
printf("%f\n", currentBalance);
return 0;
}
|
The following table shows the value of currentBalance returned for various arguments.
Input | currentBalance |
---|---|
25 | 25.00000 |
infinity | inf |
inf | inf |
-infinity | -inf |
NaN | nan |
nan | nan |
1e9999 | inf |
-1e9999 | -inf |
As this example demonstrates, the user can enter the exceptional values infinity and NaN, as well as force a float's value to be infinite by entering out-of-range floats. These entries subsequently corrupt the value of currentBalance. So by entering exceptional floats, an attacker can corrupt the program data, possibly leading to a crash.
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.
Code Block | ||
---|---|---|
| ||
doublefloat currentBalance; /* User's cash balance */ void doDeposit(){ doublefloat val; scanf("%g%f", &val); int k=isinf(x); if (k==1){ /* handle infinity error */ } if (k==-1){ /* handle negative infinity error */ } if(isnan(val)) /* test NaN */ { /* handle NaN error */ } if(val>=MAX_VALUE-currentBalance) { /*Handle range error*/ } currentBalance+=val; } |
...