FIO17-C. Do not rely on an ending null character when using fread()
The fread() function, as defined in the C Standard, subclause 7.21.8.1 [ ISO/IEC 9899:2011 ], does not explicitly null-terminate the read character sequence.
Synopsis
size_t fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream)Description
Thefreadfunction reads, into the array pointed to byptr, up tonmembelements
whose size is specified bysize, from the stream pointed to bystream.
Although the content of a file has a properly null-terminated character sequence, if nmemb is less than the total length of the characters, the fread() function will not read after nmemb characters. fread() will not append a null character to the end of the string being read to.
Noncompliant Code Example
Suppose we have a null-terminated character sequence in a file, and we need to extract a null-terminated byte string:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
FILE *fp;
size_t size;
long length;
char *buffer;
fp = fopen("file.txt", "rb");
if (fp == NULL) {
/* Handle file open error */
}
/* Obtain file size */
if (fseek(fp, 0, SEEK_END) != 0) {
/* Handle repositioning error */
}
length = ftell(fp);
if (fseek(fp, 0L, SEEK_SET) != 0) {
/* Handle repositioning error */
}
/* Allocate memory to contain whole file */
buffer = (char*) malloc(length);
if (buffer == NULL) {
/* Handle memory allocation error */
}
/* size assigned here in some other code */
if (fread(buffer, 1, size, fp) < size) {
/* Handle file read error */
}
fclose(fp);
return 0;
}
When size is less than the total length of the file ( file.txt ), buffer is not properly null-terminated.
Compliant Solution
To correct this example, the size of buffer must be compared with the total length of the file to identify the erroneous case where size differs from length . At this point, it is up to the programmer to handle this case.
#include <stdio.h>
#include <stdlib.h>
int main (void) {
FILE *fp;
size_t size;
long length;
char *buffer;
fp = fopen("file.txt", "rb");
if (fp == NULL) {
/* Handle file open error */
}
/* Obtain file size */
if (fseek(fp, 0, SEEK_END) != 0) {
/* Handle repositioning error */
}
length = ftell(fp);
if (fseek(fp, 0L, SEEK_SET) != 0) {
/* Handle repositioning error */
}
/* Allocate memory to contain whole file */
buffer = (char*) malloc(length);
if (buffer == NULL) {
/* Handle memory allocation error */
}
/* ... Assign size here ... */
if (length != size) {
/* Handle case when size isn't the length of file */
}
/* ... Other code ... */
if (fread(buffer, 1, size, fp) < size) {
/* Handle file read error */
}
fclose(fp);
return 0;
}
Risk Assessment
When reading an input stream, the read character sequence is not explicitly null-terminated by the fread() function. Operations on the read-to buffer could result in overruns, causing abnormal program termination .
| Rule | Severity | Likelihood | Detectable | Repairable | Priority | Level |
|---|---|---|---|---|---|---|
| FIO17-C | Low | Likely | No | Yes | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description |
|---|---|---|---|
| LDRA tool suite | 9.7.1 | 44 S | Enhanced enforcement |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website .
Related Guidelines
| SEI CERT C++ Coding Standard | VOID FIO20-CPP. Do not rely on an ending null character when using read() |
Bibliography
| [ ISO/IEC 9899:2011 ] | Subclause 7.21.8.1, "The fread Function" |


