How to Read Entire Line When Buffer Is Small Fgets

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

Noncompliant Lawmaking Example

This noncompliant lawmaking 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 simulated; }   void func(void) {   char buf[8];   if (get_data(buf, sizeof(buf))) {     printf("The user input %southward\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 instance, because the buffer is only eight characters in length, if the user input "Hello World\n", the buffer would contain "How-do-you-do W" terminated past a zip character.

Compliant Solution (Fail on Truncation)

This compliant solution examines the end-of-file marker for the stream and the concluding character in the buffer to determine whether it is a newline or not.  If it is the terminate of file, or the last graphic symbol 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) || (len != 0 && buffer[len-1] == '\n');   }   return simulated; }   void func(void) {   char buf[8];   if (get_data(buf, sizeof(buf))) {     printf("The user input %southward\n", buf);   } else {     printf("Error getting information from the user\due north");   } }

Compliant Solution (Expanding Buffer)

This compliant solution solves the problem past expanding the buffer to read the unabridged contents fromstdin instead of failing if the caller did not allocate enough infinite.  If the allocation fails, it volition render Naught, just otherwise, information technology returns a buffer of the received data, which the caller must gratuitous.

#include <stdio.h> #include <stdlib.h> #include <string.h>  char *get_filled_buffer(void) {   char temp[32];   char *ret = Cipher;   size_t full_length = 0;       while (fgets(temp, sizeof(temp), stdin)) {     size_t len = strlen(temp);     if (SIZE_MAX - len - 1 < full_length) {       intermission;     }     char *r_temp = realloc(ret, full_length + len + 1);     if (r_temp == NULL) {       interruption;     }     ret = r_temp;     strcpy(ret + full_length, temp); /* concatenate */     full_length += len;         if (feof(stdin) || temp[len-1] == '\north') {       return ret;     }   }    complimentary(ret);   return NULL; }

Compliant Solution (POSIX getline())

Thegetline() function was originally a GNU extension, but is now standard in POSIX.1-2008. It also fills a string with characters from an input stream. In this case, the program passes it a NULL arrow for a string, indicating thatgetline() should allocate sufficient space for the string and the caller frees it afterwards.

#include <stdio.h>  void func(void) {   char* buf = Zip;   size_t dummy = 0;   if (getline(&buf, &dummy, stdin) == -1) { 	/* handle error */   }   printf("The user input %s\n", buf);   free(buf); }

Run a risk Assessment

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

Recommendation

Severity

Likelihood

Remediation Toll

Priority

Level

FIO20-C

Medium

Probable

Medium

P12

L1

Automated Detection

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

Bibliography


martinwhousee.blogspot.com

Source: https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152445

0 Response to "How to Read Entire Line When Buffer Is Small Fgets"

ارسال یک نظر

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel