A call to the std::basic_filebuf<T>::open()
function must be matched with a call to std::basic_filebuf<T>::close()
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.
Note that std::basic_ifstream<T>
, std::basic_ofstream<T>
, and std::basic_fstream<T>
all maintain an internal reference to a std::basic_filebuf<T>
object on which open()
and close()
are called as needed. Properly managing an object of one of these types (by not leaking the object) is sufficient to ensure compliance with this rule. Often, the best solution is to use the stream object by value semantics instead of via dynamic memory allocation, ensuring compliance with MEM51-CPP. Properly deallocate dynamically allocated resources. However, that is still insufficient for situations in which destructors are not automatically called.
Noncompliant Code Example
In this noncompliant code example, a std::fstream
object f
is constructed. The constructor for std::fstream
calls std::basic_filebuf<T>::open()
, and the default std::terminate_handler
called by std::terminate()
is std::abort()
, which does not call destructors. Consequently, the underlying std::basic_filebuf<T>
object maintained by the object is not properly closed, and the program has no way of determining whether an error occurs while flushing or closing the file.
#include <exception> #include <fstream> #include <string> void f(const std::string &N) { std::fstream f(N); if (!f.is_open()) { // Handle error return; } // ... std::terminate(); }
Compliant Solution
In this compliant solution, std::fstream::close()
is called before std::terminate()
is called, ensuring that the file resources are properly closed:
#include <exception> #include <fstream> #include <string> void f(const std::string &N) { std::fstream f(N); if (!f.is_open()) { // Handle error return; } // ... f.close(); if (f.fail()) { // Handle error } std::terminate(); }
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 |
---|---|---|---|---|---|
FIO51-CPP | Medium | Unlikely | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
CodeSonar | 8.1p0 | ALLOC.LEAK | Leak |
Parasoft C/C++test | 9.5 | BD-RES-LEAKS | |
Parasoft Insure++ | Runtime detection |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | MEM51-CPP. Properly deallocate dynamically allocated resources |
SEI CERT C Coding Standard | FIO42-C. Close files when they are no longer needed |
Bibliography
[ISO/IEC 14882-2014] | Subclause 27.9.1, "File Streams" |