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

Compare with Current View Page History

« Previous Version 40 Next »

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

In general, this rule 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.

Noncompliant Code Example

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

#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:

#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.

#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:

#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:

#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)

In this compliant solution, fd is closed before returning to the caller:

#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)) {
    return -1;
  }
  return 0;
}

Noncompliant Code Example (Windows)

In this noncompliant code example, the file opened by the Microsoft Windows CreateFile() function is not closed before func() returns:

#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 by invoking the CloseHandle() function before returning to the caller:

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

Risk Assessment

Failing to properly close files may allow an attacker to exhaust system resources and 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

Automated Detection

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

Tool

Version

Checker

Description

CodeSonar8.1p0ALLOC.LEAKLeak
Compass/ROSE   
Klocwork2024.1

RH.LEAK

 
LDRA tool suite9.7.1

49 D

Partially implemented
Parasoft C/C++test9.5BD-RES-LEAKS 
Polyspace Bug FinderR2016aResource leak

File stream not closed before FILE pointer scope ends or pointer is reassigned

SonarQube C/C++ Plugin

3.11

S2095 

Related Vulnerabilities

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

Related Guidelines

Bibliography

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

 


  • No labels