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;
}

Noncompliant Code Example (exit())

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, the program has no way of determining if an error occurs while flushing or closing the file.

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

Compliant Solution (exit())

In this compliant solution, the program closes f explicitly before calling exit(), allowing 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

Detectable

Repairable

Priority

Level

FIO42-C

Medium

Unlikely

Medium

No

No

P4

P2

L3

Automated Detection

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.

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

Supported, but no explicit checker
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
ALLOC.LEAKLeak
Compass/ROSE
   

Fortify SCA

5.0

 Can detect violations of this rule with CERT C Rule Pack



Coverity
Include Page
Coverity_V
Coverity_V

RESOURCE_LEAK (partial)

Partially implemented
Cppcheck

Include Page
Cppcheck_V
Cppcheck_V

resourceLeak
Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

resourceLeak
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF2701, DF2702, DF2703


Klocwork
Include Page
Klocwork_V
Klocwork_V

RH.LEAK

 


LDRA tool suite
Include Page
LDRA_V
LDRA_V

49 D

Partially implemented
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-FIO42-a

Ensure resources are freed

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

429

Partially supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule FIO42-CChecks for resource leak (rule partially covered)
Security Reviewer - Static Reviewer

Include Page
Security Reviewer - Static Reviewer_V
Security Reviewer - Static Reviewer_V

C80Fully implemented
SonarQube C/C++ Plugin

Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V

S2095

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 Standard
FIO42
FIO51-CPP.
Ensure
Close files
are properly closed
when they are no longer neededPrior to 2018-01-12: CERT: Unspecified Relationship
CERT Oracle Secure Coding Standard for JavaFIO04-J. Release resources when they are no longer neededPrior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TS 17961:2013Failing to close files or free dynamic memory when they are no longer needed [fileclose]
MITRE CWE
Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-404, Improper
resource shutdown or release
Resource Shutdown or Release2017-07-06: CERT: Rule subset of CWE
CWE 2.11CWE-4592017-07-06: CERT: Rule subset of CWE
CWE 2.11CWE-7722017-07-06: CERT: Rule subset of CWE
CWE 2.11CWE-7732017-07-06: CERT: Rule subset of CWE
CWE 2.11CWE-7752017-07-06: CERT: Rule subset of CWE
CWE 2.11CWE-403

2017-10-30:MITRE:Unspecified Relationship

2018-10-18:CERT:Partial overlap

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-773/CWE-775 and FIO42-C

CWE-773 = CWE-775

CWE-773 = Union( FIO42-C, list) where list =

  • Failure to free resource handles besides files

CWE-404/CWE-459/CWE-771/CWE-772 and FIO42-C/MEM31-C

Intersection( FIO42-C, MEM31-C) = Ø

CWE-404 = CWE-459 = CWE-771 = CWE-772

CWE-404 = Union( FIO42-C, MEM31-C list) where list =

  • Failure to free resources besides files or memory chunks, such as mutexes)

CWE-403 and FIO42-C

CWE-403 FIO42-C = list, where list =

  • A process opens and closes a sensitive file descriptor, but also executes a child process while the file descriptor is open.

FIO42-C - CWE-403 = SPECIAL_CASES, where SPECIAL_CASES =

  • A program opens a file descriptor and fails to close it, but does not invoke any child processes while the file descriptor is open.

Bibliography

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

...


...

Image Modified Image Modified Image Modified