Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

A call to the fopen() or freopen() function must be matched with a call to fclose() before the lifetime of the last pointer object that stores the return value of the call has ended , or before normal program termination, whichever occurs first.

In general, this rule can should also be applied to other functions with open and close resources, such as the POSIX open() and close() functions, or the Microsoft Windows CreateFile() and CloseHandle() functions.

...

This code example is noncompliant because the resource allocated file opened by the call to fopen() is not closed before function func() returns.:

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
 
int func(const char *filename) {
  FILE *f = fopen(filename, "r"); 
  if (NULL == f) {
    return -1;
  }

  /* ... */

  return 0;
}

Compliant Solution

In this compliant solution,  the file pointed to by f is closed before returning to the caller:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
 
int func(const char *filename) {
  FILE *f = fopen(filename, "r"); 
  if (NULL == f) {
    return -1;
  }

  /* ... */

  if (fclose(f) == EOF) {
    return -1;
  }
  return 0;
}

...

This code example is noncompliant because the resource allocated by the call to fopen() is not closed before the program terminates.  Although exit() closes the file, if any the program has no way of determining if an error occurs when while flushing or closing the file, the program has no way of knowing about it.

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
#include <stdlib.h>
  
int main(void) {
  FILE *f = fopen(filename, "w"); 
  if (NULL == f) {
    /* Handle error */exit(EXIT_FAILURE);
  }

  /* ... */

  exit(EXIT_SUCCESS);
}

Compliant Solution (exit())

In this compliant solution, the program closes f explicitly before it calls calling exit(), allowing it to handle any error that occurs when flushing or closing the file to be handled appropriately:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <stdlib.h>

int main(void) {
  FILE *f = fopen(filename, "w"); 
  if (NULL == f) {
    /* Handle error */
  }

  /* ... */

  if (fclose(f) == EOF) {
    /* Handle error */
  }

  exit(EXIT_SUCCESS);
}

Noncompliant Code Example (POSIX)

This code example is noncompliant because the resource allocated by the call to open() is not closed before function func() returns.:

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
#include <fcntl.h>
 
int func(const char *filename) {
  int fd = open(filename, O_RDONLY, S_IRUSR);
  if (-1 == fd) {
    return -1
  }

  /* ... */

  return 0;
}

Compliant Solution (POSIX)

...

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
 
int func(const char *filename) {
  int fd = open(filename, O_RDONLY, S_IRUSR);
  if (-1 == fd) {
    return -1
  }

  /* ... */

  if (-1 == close(fd) == -1) {
    return -1;
  }
  return 0;
}

...

In this noncompliant code example, a the file is opened using by the Microsoft Windows CreateFile() API, but it function is not subsequently closed before func() returns.:

Code Block
bgColor#FFcccc
langc
#include <Windows.h>
 
int func(LPCTSTR filename) {
  HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, NULL);
  if (INVALID_HANDLE_VALUE == hFile) {
    return -1;
  }
 
  /* ... */
 
  return 0;
}

Compliant Solution (Windows)

In this compliant solution, hFile is closed using by invoking the CloseHandle() API function before returning to the caller.:

Code Block
bgColor#ccccff
langc
#include <Windows.h>
 
int func(LPCTSTR filename) {
  HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, NULL);
  if (INVALID_HANDLE_VALUE == hFile) {
    return -1;
  }
 
  /* ... */
 
  if (!CloseHandle(hFile)) {
    return -1;
  }
 
  return 0;
}

...

Failing to properly close files may allow an attacker to exhaust system resources and increases can increase the risk that data written into in-memory file buffers will not be flushed in the event of abnormal program termination. .

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO42-C

Medium

Unlikely

Medium

P4

L3

...

This rule is stricter than rule [fileclose] in ISO/IEC TS 17961:2013. Analyzers that conform to the TS technical standard may not detect all violations of this rule.

...

Bibliography

[IEEE Std 1003.1:2013]XSH, System Interfaces, open

...