Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: axivion tool

When one has you have a choice of two functions to accomplish the same task, prefer the one with better error checking and reporting.

The following table shows a list of C standard library functions that provide limited or no error checking and reporting along with preferable alternatives:

Function

Preferable
Alternative

Comments

atof

strtod

No error indication, undefined behavior on error

atoi

strtol

No error indication, undefined behavior on error

atol

strtol

No error indication, undefined behavior on error

atoll

strtoll

No error indication, undefined behavior on error

rewind

fseek

No error indication, silent failure on error

setbuf

setvbuf

No error indication, silent failure on error

ctimeasctime/localtime 

Undefined behavior if localtime fails 

Noncompliant Code Example (atoi())

This noncompliant code example converts the string token stored in the static array buff to a signed integer value using the atoi() function.:

Code Block
bgColor#FFcccc
langc

int si;

if (argc > 1) {
  si = atoi(argv[1]);
}

The atoi(), atol(), and atoll() functions convert the initial portion of a string token to int, long int, and long long int representation , respectively. Except for the behavior on error, they are equivalent to

...

as follows:

Call

Equivalent on Success

atoi(nptr)

(int)strtol(nptr,

...

(char

...

**)NULL,

...

10)

...

atol(nptr)

strtol(nptr,

...

(char

...

**)NULL,

...

10)

...

atoll(nptr)

strtoll(nptr,

...

(char

...

**)NULL,

...

10)

...

Unfortunately, atoi() and related functions lack a mechanism for reporting errors for invalid values. Specifically, the atoi(), atol(), and atoll() functions

  • do Do not need to set errno on an error.
  • have Have undefined behavior if the value of the result cannot be represented. (See undefined behavior 119 of Annex J of the C Standard.)
  • Return return 0 if the string does not represent an integer , (which is indistinguishable from a correctly formatted, zero-denoting input string), but the C Standard only specifies the behavior of these functions on success.

See also MSC24-C. Do not use deprecated or obsolescent functions.

Compliant Solution (strtol())

The strtol(), strtoll(), strtoul(), and strtoull() functions convert a null-terminated byte string to long int, long long int, unsigned long int, and unsigned long long int representation , respectively.

This compliant solution uses strtol() to convert a string token to an integer and ensures that the value is in the range of int.:

Code Block
bgColor#ccccff
langc

long sl;
int si;
char *end_ptr;

if (argc > 1) {
  errno = 0;

  sl = strtol(argv[1], &end_ptr, 10);

  if ((sl == LONG_MIN)
   || (sl == LONG_MAX) 
   || (end_ptr == argv[1]))
  {
    if (&& errno != 0)
  {
      perror("strtol error");
    }
  else  elseif (end_ptr == argv[1]) {
      if (puts("error encountered during conversion") == EOF) {
        /* Handle Errorerror */
      }
    }
  }
  else if (sl > INT_MAX) {
    printf("%ld too large!\n", sl);
  }
  else if (sl < INT_MIN) {
    printf("%ld too small!\n", sl);
  }
  else if ('\0' != *end_ptr) {
    if (puts("extra characters on input line\n") == EOF) {
      /* Handle Errorerror */
    }
  }
  else {
    si = (int)sl;
  }
}

Both the non-compliant noncompliant code example and compliant the compliant solution are taken from INT06ERR34-C. Use strtol() or a related function to convert a string token to an integerDetect errors when converting a string to a number.

Noncompliant Code Example (rewind())

This noncompliant code example sets the file position indicator of an input stream back to the beginning using rewind().:

Code Block
bgColor#ffcccc
langc

char *file_name;
FILE *fp;

/* initializeInitialize file_name */

fp = fopen(file_name, "r");
if (fp == NULL) {
  /* Handle open error */
}

/* readRead data */

rewind(fp);

/* continueContinue */

However, it It is impossible to determine if rewind() succeeded.

...

This compliant solution uses fseek() instead of rewind() and checks to see if the operation succeeded.:

Code Block
bgColor#ccccff
langc

char *file_name;
FILE *fp;

/* initializeInitialize file_name */

fp = fopen(file_name, "r");
if (fp == NULL) {
  /* Handle open error */
}

/* readRead data */

if (fseek(fp, 0L, SEEK_SET) != 0) {
  /* Handle repositioning error */
}

/* continueContinue */

...

Noncompliant Code Example (setbuf())

This noncompliant code example calls setbuf() with a buf argument of NULL.:

Code Block
bgColor#ffcccc
langc

FILE *file;
/* Setup file */
setbuf(file, NULL);
/* ... */

...

This compliant solution calls setvbuf(), which returns nonzero if the operation failed.:

Code Block
bgColor#ccccff
langc

FILE *file;
char *buf = NULL;
/* Setup file */
if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
  /* Handle error */
}
/* ... */

Both the non-compliant code example and compliant solution are taken from FIO07-C. Prefer fseek() to rewind().

Risk Assessment

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

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

INT06

ERR07-C

medium

Medium

probable

Probable

medium

Medium

P8

L2

Automated Detection

This rule in general cannot be detected, although various examples can be detected by simply scanning for functions that have equivalent functions with better error handling.

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
bad-functionFully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-ERR07
LDRA tool suite
Include Page
LDRA_V
LDRA_V

44 S, 593 S, 594 S

Partially implemented
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-ERR07-a
CERT_C-ERR07-b

The library functions atof, atoi and atol from library stdlib.h shall not be used
The Standard Library input/output functions shall not be used

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

586

Fully supported

RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
bad-functionFully checked

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[Klein 02|AA. C References#Klein 02]\]
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.1.4, "The {{strtol}}, {{strtoll}}, {{strtoul}}, and {{strtoull}} functions," Section 7.20.1.2, "The {{atoi}}, {{atol}}, and {{atoll}} functions," Section 7.19.6.7, "The {{sscanf}} function," Section 7.19.5.5, "The {{setbuf}} function", Section 7.19.9.2, "The fseek function"; 7.19.9.5, and "The rewind function"
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 676|http://cwe.mitre.org/data/definitions/676.html], "Use of Potentially Dangerous Function," and [CWE ID 20|http://cwe.mitre.org/data/definitions/20.html], "Insufficient Input Validation"

Related Guidelines

MITRE CWECWE-20, Improper Input Validation
CWE-79, Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE-89, Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
CWE-91, XML Injection (aka Blind XPath Injection)
CWE-94, Improper Control of Generation of Code ('Code Injection')
CWE-114, Process Control
CWE-601, URL Redirection to Untrusted Site ('Open Redirect')
CWE-676, Use of potentially dangerous function

Bibliography

[Klein 2002]"Bullet Proof Integer Input Using strtol()"


...

Image Added Image Added Image AddedImage Removed      12. Error Handling (ERR)       ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failure