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

Compare with Current View Page History

« Previous Version 52 Next »

The fgets() and fgetws() functions are typically used to read a newline-terminated line of input from a stream. Both functions read at most one less than the number of narrow or wide characters specified by an argument n from a stream to a string. Truncation errors can occur if n - 1 is less than the number of characters appearing in the input string prior to the new-line narrow or wide character (which is retained) or after end-of-file.  This can result in the accidental truncation of user input.

Noncompliant Code Example

This noncompliant code example copies the input string into a buffer, and assumes it captured all of the user's input.

#include <stdbool.h>
#include <stdio.h>
 
bool get_data(char *buffer, int size) {
  if (fgets(buffer, size, stdin)) {
    return true;
  }
  return false;
}
 
void func(void) {
  char buf[8];
  if (get_data(buf, sizeof(buf))) {
    printf("The user input %s\n", buf);
  } else {
    printf("Error getting data from the user\n");
  }
}

However, if the last character in buf is not a newline and the stream is not at the end-of-file marker, the buffer was too small to contain all of the data from the user.  For example, because the buffer is only 8 characters in length, if the user input "Hello World\n", the buffer would contain "Hello W" terminated by a null character.

Compliant Solution

This compliant solution examines the end-of-file marker for the stream and the last character in the buffer to determine whether it is a newline or not.  If it is the end of file, or the last character is a newline, then the buffer contains all of the user's input.  However, if the last character is not at the end-of-file and not a newline then the user's input has been truncated.

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
 
bool get_data(char *buffer, int size) {
  if (fgets(buffer, size, stdin)) {
    size_t len = strlen(buffer);
    return feof(stdin) || buffer[len] == '\n'; 
  }
  return false;
}
 
void func(void) {
  char buf[8];
  if (get_data(buf, sizeof(buf))) {
    printf("The user input %s\n", buf);
  } else {
    printf("Error getting data from the user\n");
  }
}

Risk Assessment

Incorrectly assuming a newline character is read by fgets() or fgetws() can result in data truncation.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO36-C

medium

likely

medium

P12

L1

Related Vulnerabilities

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

Related Guidelines

Bibliography

[Lai 2006] 
[Seacord 2013]Chapter 2, "Strings"

 


 

  • No labels