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

Compare with Current View Page History

« Previous Version 70 Next »

Do not use functions that input characters and convert them to integers if the functions cannot handle all possible inputs. For example, formatted input functions such as scanf(), fscanf(), vscanf(), and vfscanf() can be used to read string data from stdin or (in the cases of fscanf() and vfscanf()) other input streams. These functions work fine for valid integer values but lack robust error handling for invalid values.

Alternatively, input character data as a null-terminated byte string and convert to an integer value using strtol() or a related function (see INT06-C. Use strtol() or a related function to convert a string token to an integer).

Noncompliant Code Example

This noncompliant code example uses the scanf() function to read a string from stdin and convert it to a long. The scanf() and fscanf() functions have undefined behavior if the value of the result of this operation cannot be represented as an integer.

long sl;

if (scanf("%ld", &sl) != 1) {
  /* handle error */
}

In general, do not use scanf() to parse integers or floating-point numbers from input strings, because the input could contain numbers not representable by the argument type.

Compliant Solution (Linux)

This compliant example uses the Linux scanf() implementation's built in error handling to validate input. On Linux platforms, scanf() sets errno to ERANGE if the result of integer conversion cannot be represented within the size specified by the format string [Linux 08]. Note that this is a platform dependent solution. Therefore, this should only be used where portability is not a concern.

long sl;
errno = 0;

if (scanf("%ld", &sl) != 1) {
  /* handle error */
}
else if (ERANGE == errno) {
  if (puts("number out of range\n") == EOF) {
      /* Handle error */
  }
}

Compliant Solution

This compliant example uses fgets() to input a string and strtol() to convert the string to an integer. Error checking is provided to make sure that the value is a valid integer in the range of long.

char buff[25];
char *end_ptr;
long sl;

if (fgets(buff, sizeof(buff), stdin) == NULL) {
  if (puts("EOF or read error\n") == EOF) {
    /* Handle error */
  }
} else {
  errno = 0;

  sl = strtol(buff, &end_ptr, 10);

  if (ERANGE == errno) {
    if (puts("number out of range\n") == EOF) {
      /* Handle error */
    }
  }
  else if (end_ptr == buff) {
    if (puts("not valid numeric input\n") == EOF) {
      /* Handle error */
    }
  }
  else if ('\n' != *end_ptr && '\0' != *end_ptr) {
    if (puts("extra characters on input line\n") == EOF) {
      /* Handle error */
    }
  }
}

Note that this solution treats any trailing characters, including white-space characters, as an error condition.

Risk Assessment

While it is relatively rare for a violation of this recommendation to result in a security vulnerability, it can easily result in lost or misinterpreted data.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

INT05-C

medium

probable

high

P4

L3

Automated Detection

Fortify SCA Version 5.0 with the CERT C Rule Pack can detect violations of this recommendation.

Compass/ROSE can detect violations of this recommendation. In particular, it notes uses of the scanf() family of functions where on the type specifier is a floating point or integer type.

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 INT05-CPP. Do not use input functions to convert character data if they cannot handle all possible inputs.

References

[Klein 02]
[ISO/IEC 9899:1999] Section 7.20.1.4, "The strtol, strtoll, strtoul, and strtoull functions," and Section 7.19.6, "Formatted input/output functions"
[MITRE 07] CWE ID 192, "Integer Coercion Error"; and CWE ID 197, "Numeric Truncation Error"
[Linux 08] scanf(3)


INT04-C. Enforce limits on integer values originating from untrusted sources      04. Integers (INT)      INT06-C. Use strtol() or a related function to convert a string token to an integer

  • No labels