Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM Cost Reform

Errors can occur when incorrect assumptions are made about the type of data being read. These assumptions may be violated, for example, when binary data has been read from a file instead of text from a user's terminal or the output of a process is piped to stdin. (See recommendation FIO14-C. Understand the difference between text mode and binary mode with file streams.) On some systems, it may also be possible to input a null byte (as well as other binary codes) from the keyboard.

C99, Section Subclause 7.1923.7.2 , "The fgets function", paragraph 3 saysof the C Standard paragraph 3 [ISO/IEC 9899:2024] says,

The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the members of the array have unspecified values and a null pointer is returned.

The wide-character function fgetws() has the same behavior. Therefore, if fgets() returns  or fgetws() returns a non-null pointer, we can assume it actually filled it is safe to assume that the array with contains data. However, assuming that it filled it is erroneous to assume that the array with a non-empty null-terminated byte string (NTBS) is erroneous contains a nonempty string because the data it placed in the array may contain null characters.

Noncompliant Code Example

This noncompliant code example attempts to remove the trailing new-line newline (\n) from an input line. The fgets() function is typically used to read a newnewline-line terminated - line of input from a stream. It takes a size parameter for the destination buffer and copies, at most, size - 1 characters from a stream to a character array.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <string.h>
 
enum { BUFFER_SIZE = 1024 };

void func(void) {
  char buf[BUFSIZ + 1BUFFER_SIZE];

  if (fgets(buf, sizeof(buf), stdin) == NULL) {
    /* Handle error */
  }
  buf[strlen(buf) - 1] = '\0';
}

The strlen() function computes the length of a string by determining the number of characters that precede the terminating null character. A problem occurs if the first character read from the input by fgets() happens to be a null character. This may occur, for example, if a binary data file is read by the fgets() call [Lai 2006]. If the first character in buf is a null character, strlen(buf) returns 0, the expression strlen(buf) - 1 wraps around to a large positive value, and a write-outside-array-bounds error occurs.

Compliant Solution

This compliant solution uses strchr() to replace the new-line newline character in the string , if it exists. (See rue FIO36-C. Do not assume a new-line character is read when using fgets().):

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <string.h>
 
enum { BUFFER_SIZE = 1024 };

void func(void) {
  char buf[BUFSIZ + 1BUFFER_SIZE];
  char *p;

  if (fgets(buf, sizeof(buf), stdin)) {
    p = strchr(buf, '\n');
    if (p) {
      *p = '\0';
    }
  }
 else {
    /* Handle error condition */
  }
}

Risk Assessment

Assuming Incorrectly assuming that character data has been read can result in an out-of-bounds memory write or other flawed logic.

Rule

Severity

Likelihood

Detectable

Remediation Cost

Repairable

Priority

Level

FIO37-C

high

High

Probable

probable

Yes

medium

Yes

P12

P18

L1

Automated Detection

Tool

Version

Checker

Description

section

Astrée

Fortify SCA

Include Page
Astrée_V
Astrée_V

Supported: Astrée reports defects due to returned (empty) strings.
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-FIO37

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
(general)Considers the possibility that fgets() and fgetws() may return empty strings (Warnings of various classes may be triggered depending on subsequent operations on those strings. For example, the noncompliant code example cited above would trigger a buffer underrun warning.)
Section

V. 5.0

 

 

section

Compass/ROSE

 

 

Sectioncould



Could detect some violations of this rule

.

(In particular, it could detect

the NCCE by

the noncompliant code example by searching for fgets(), followed by

"

strlen() - 1

"

, which could be

-1

−1. The crux of this rule is that a string returned by fgets() could still be empty, because the first char is '\0'. There are probably other code examples that violate this guideline;

we

 they would need to

enumerate them

be enumerated before ROSE could detect them.)


Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-fio37-c

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF4911, DF4912, DF4913



 Klocwork

Include Page
Klocwork_V
Klocwork_V

CERT.FIO.FGETS



LDRA tool suite
Include Page
LDRA_V
LDRA_V
44 SEnhanced enforcement
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-FIO37-a

Avoid accessing arrays out of bounds
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule FIO37-CChecks for use of indeterminate string (rule fully covered)

Related Vulnerabilities

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

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT C Secure Coding StandardFIO14-C. Understand the difference between text mode and binary mode with file streamsPrior to 2018-01-12: CERT: Unspecified Relationship
CERT C

...

Secure Coding StandardFIO20-C. Avoid unintentional truncation when using fgets() or fgetws()Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-241, Improper Handling of Unexpected Data Type2017-07-05: CERT:

...

Rule subset of CWE

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-241 and FIO37-C

CWE-241 = Union( FIO37-C, list) where list =

  • Improper handling of unexpected data type that does not come from the fgets() function.

Bibliography

...

2024]

Subclause 7.

...

23.7.2, "The fgets

...

Function"

MITRE CWE: CWE-119, "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer"

MITRE CWE: CWE-241, "Failure to Handle Wrong Data Type"

...

Subclause 7.31.3.2, "The fgetws Function"

[Lai 2006]
[Seacord

...

2013]Chapter 2, "Strings"


...

Image Modified Image Modified Image Modified